Cannot fetch the latest record from the database - java

I am trying to get the latest record from the Database (Derby database).
I have a BILL table in the database that has a column BillId. The data type of BillId is varchar(15) and is in the format as:
3122022-1
The digits before the "-" (i.e., 3122022) are according to the date (3/12/2002). The value after the "-" is the bill counter (i.e., 1).
The problem is, when I try to get the latest record from the database using max(BILLID), it considers 3122022-9 as the maximum/latest record even if the billId 3122022-10 or higher exists.
In simple words, it ignores the 0 or any value placed at the second place after "-". Why is this issue happening and what is the solution??
Here is the table structure:
Bill table
I used the following query:
select max(billId) as lastBill from Bill where empName='Hassan' and Date=Current Date;
empName is important as there are 4-5 employees and each will have their own count of Bill.
If I run this query:
select billid from bill order by empName desc;
I get this result:
Bill ids when I sort them by empName column
But if I run the max(billId) query, This is what I get:
select max(billId) as lastBill from Bill where empName='Hassan' and Date=Current Date;
max(billid) results
I hope I was able to explain my question well. Will be grateful for your help and support.
I tried max(billId)

i came up with sample dataset and query.
//Postgres sql
with data as
(
select 'A' as emp_name,'03122022-1' as dated_on
union
select 'A' as emp_name,'03122022-2' as dated_on
union
select 'A' as emp_name,'03122022-3' as dated_on
union
select 'A' as emp_name,'03122022-4' as dated_on
union
select 'A' as emp_name,'03122022-5' as dated_on
union
select 'A' as emp_name,'03122022-6' as dated_on
)
,
data_clean as (
select emp_name,dated_on,
to_date((regexp_split_to_array (dated_on,'-'))[1],'DDMMYYYY') as bill_dated_on,
(regexp_split_to_array (dated_on,'-'))[2] ::int as bill_id
from data)
select emp_name,max(bill_id) from data_clean
where bill_dated_on='20221203'
group by emp_name;
emp_name|max|
--------+---+
A | 6|

Related

SQL for return all the id which does not exist in db and passing in sql

I need some help writing an SQL statement for the below requirement.
I have list of employee_id which I need to check whether they are exist in the DB or not from the java layer I want to use one query for this.
Sample query:
SELECT *
FROM employee
WHERE employee_id IN (1001,1002,1002,10000004).
In this query 10000004 does not exist in DB.
One approach in my mind is to use the below query:
SELECT Count(employee_id)
FROM employee
WHERE employee_id IN (1001,1002,1002,10000004).
Then check the list size and the result from the query in java layer. But I don’t want this because I need all those employee_id which does not exist in DB.
declare #employeeids varchar(1000) --to store ids as comma seperated string
declare #tmpEmployee table (employee_id varchar(50)) --temp employee table to store ids from string
declare #pointer int
select #employeeids = '1001,1002,1002,10000004' --list of ids to check against database
while (charindex(',', #employeeids, 0) > 0)
begin
set #pointer = charindex(',', #employeeids, 0)
insert into #tmpEmployee (employee_id)
--remove white spaces if exists
select ltrim(rtrim(substring(#employeeids, 0, #pointer)))
set #employeeids = stuff(#employeeids, 1, #pointer, '')
end
insert into #tmpEmployee (employee_id)
select ltrim(rtrim(#employeeids))
select r.employee_id -- required ids which does not exists in database
,e.employee_id
from #tmpEmployee r
left join employee e on r.employee_id=e.employee_id
where e.employee_id is null
If you are using Oracle, then this link may help you. It's all about usage of built in SYS.DBMS_DEBUG_VC2COLL function
Exist a very bad way to do that is this:
SELECT * FROM (SELECT 5930 id UNION SELECT 8109 id
UNION SELECT 8110 id UNION SELECT 8115 id UNION SELECT 8112 id
UNION SELECT 8113 id UNION SELECT -1 id) b
WHERE b.id NOT IN (SELECT f.id FROM employee f)
I recommed you do that in other way.

How can I create rows for dates missing from a range?

I am trying to get data for all dates in a range provided by my query, but I'm only getting the dates that actually exist in my table - missing dates are not reported. I need to create records in the table for those missing dates, with other columns left null, and then include them in the results.
My table table_name has records like:
ID Name Date_only
---- ---- -----------
1234 xyz 01-Jan-2014
1234 xyz 02-Jan-2014
1234 xyz 04-Jan-2014
...
For example, for the range 01-Jan-2014 to 04-Jan-2014, my query is:
select * from table_name
where id=1234
and (date_only >= '01-Jan-14' and date_only <= '04-Jan-14')
From Java or queried directly this shows three rows, with no data for 03-Jan-2014.
I need a single statement to insert rows for any missing dates into the table and return the data for all four rows. How can I do that?
UPDATE
Followed query worked for only if only 1 record available in table OR search range 2-5 days,
SELECT LEVEL, to_date('2014-11-08','yyyy-mm-dd') + level as day_as_date FROM DUAL CONNECT BY LEVEL <= 10 .
UPDATE WITH FIDDLE EXAMPLE
I got Error is:
I have table data and same query executed then i got error is ORA-02393: exceeded call limit on CPU usage, fiddle example is : my owntable sqlfiddle example .thanks in advance
you can use the below SQL for your purpose.The sql fiddle here http://sqlfiddle.com/#!4/3ee61/27
with start_and_end_dates as (select min(onlydate) min_date
,max(onlydate) max_date
from mytable
where id='1001'
and onlydate >= to_date('01-Jan-2015','dd-Mon-YYYY')
and onlydate <= to_date('04-Jan-2015','dd-Mon-YYYY')),
missing_dates as (select min_date + level-1 as date_value
from start_and_end_dates connect by level <=(max_date - min_date) + 1)
select distinct id,name,date_value
from mytable,missing_dates
where id='1001'
order by date_value
EDIT1:- Using your other example.The sqlfiddle is http://sqlfiddle.com/#!4/4c727/16
with start_and_end_dates as (select min(onlydate) min_date
,max(onlydate) max_date
from mytable
where name='ABCD'),
missing_dates as (select min_date + level-1 as date_value
from start_and_end_dates connect by level <=(max_date - min_date) + 1)
select distinct id,name,date_value
from mytable,missing_dates
where name='ABCD'
order by date_value;
You can use a query like
SELECT LEVEL, to_date('2014-01-01','yyyy-mm-dd') + level as day_as_date
FROM DUAL
CONNECT BY LEVEL <= 1000
to get a list of 1000 days from Jan 1 2014 (adjust to your need)
Next do an insert from select
INSERT INTO table_name (date_only)
SELECT day_as_date FROM (<<THE_QUERY_ABOVE>>)
WHERE day_as_date NOT IN (SELECT date_only FROM table_name)

Static list MINUS select statement

I have a java program that returns a list of Long values (hundreds).
I would like to subtract to this list the values obtained from a select on an oracle database,
something like this:
SELECT 23 as num FROM DUAL UNION ALL
SELECT 17 as num FROM DUAL UNION ALL
SELECT 19 as num FROM DUAL UNION ALL
SELECT 67 as num FROM DUAL UNION ALL...
...
...
SELECT 68 as num FROM DUAL MINUS
SELECT NUM FROM MYTABLE
I presume that this operation has some performance issues...
Are there other better approaches?
Thank you
Case 1:
Use Global Temporary Tables (GTT):
CREATE GLOBAL TEMPORARY TABLE my_temp_table (
column1 NUMBER
) ON COMMIT DELETE ROWS;
Insert the List (Long value) into my_temp_table:
INSERT ALL
INTO my_temp_table (column1) VALUES (27)
INTO my_temp_table (column1) VALUES (32)
INTO my_temp_table (column1) VALUES (25)
.
.
.
SELECT 1 FROM DUAL;
Then:
SELECT * FROM my_temp_table
WHERE column1 NOT IN (SELECT NUM FROM MYTABLE);
Let me know if you have any issue.
Case 2:
Use TYPE table:
CREATE TYPE number_tab IS TABLE OF number;
SELECT column_value AS num
FROM TABLE (number_tab(1,2,3,4,5,6)) temp_table
WHERE NOT EXIST (SELECT 1 FROM MYTABLE WHERE MYTABLE.NUM = temp_table.num);
Assuming MyTable is much bigger than literal values, I think the best option is using a temporary table to store your values. This way your query is a lot cleaner.
If you are working in a concurrent environment (e.g. typical web app), use an id field, and delete when finished. Summarizing:
preliminary: create a table for temporary values TEMPTABLE(id, value)
for each transaction
get new unique/atomic id (new oracle sequence value, for example)
for each literal value: insert into temptable(new_id, value)
select * from temptable where id = new_id minus...
process result
delete from temp_table where id = new_id
Temporary tables are a good solution in oracle. This one can be used with an ORM persistence layer

Java PreparedStatement can't identify placeholders in subquery

When using a Java PreparedStatement, the question-mark placeholders aren't being detected. It would throw an error "The column index is out of range: 1, number of columns: 0" when invoking statementName.setLong(1, 123). My example is from Postgres 8.4, but the problem occurs before the SQL has a chance to make it to the SQL server.
After comparing against some working prepared statements, I realized that the broken one contained a subquery similar to:
SELECT * FROM (
SELECT DISTINCT (name)
id,
name
FROM MyTable
WHERE id > ?
ORDER BY name) AS Level1
ORDER BY 1
The solution that worked for me was to convert the query to a CTE (Common Table Expression). The revised query looks like this:
WITH Level1 AS (
SELECT DISTINCT (name)
id,
name
FROM MyTable
WHERE id > ?
ORDER BY name)
SELECT *
FROM Level1
ORDER BY 1
In JDBC, the parameter indexes for prepared statements begin at 1 instead of 0.

Getting count(*) value from multiple tables

I found a solution to my query in this site. I need to get the count(*) value from multiple tables Select count(*) from multiple tables
My other problem is to get the DATE values of those multiple tables that returns > 1 row count. I have to compare the dates and get the latest. I have to query from 12 tables. Assuming I got > 1 value for tables 1, 2, 3, 4, 5, I will need to compare their DATE values.
Sample code:
SELECT(SELECT COUNT(*) FROM table1) AS count1,
(SELECT COUNT(*) FROM table2) AS count2,
(SELECT COUNT(*) FROM table3) AS count3 FROM dual
count1 count2 count3
3 2 2
I need to select the MOST RECENT date in these tables.
Select date from table1 order by date desc
Select date from table2 order by date desc
Select date from table3 order by date desc
How am I supposed to do that without table scanning?
EDIT:
Okay. The instructions said
"Get matching records from tables 1-12 using the id as the key".
If there are no records, display "No record found"
Else: get the record with the latest date by comparing data_encoded from all tables.
It's pretty hard to tell what you're after, but here's a guess:
SELECT
(SELECT MAX(date) FROM table1) AS latest1,
(SELECT MAX(date) FROM table2) AS latest2,
(SELECT MAX(date) FROM table3) AS latest3,
-- etc
FROM dual;
You can avoid table scans by having indexes on date, in which case the optimizer should do index-only scans (very fast).
have you try to group them and order it and select the first date
select ID, Date, count(date)
from table1 t1
inner join table2 t2 where t1.id = t2.id
inner join table3 t3 where t1.id = t3.id
etc..
group by date
order by date desc
something long that line

Categories