No rows fetching but need a value [duplicate] - sql

This question already has answers here:
How to return a default value when no rows are returned from the select statement
(7 answers)
Closed 8 years ago.
I need some help with the following query.
Select date, Source,count(*) as TOTALCOUNT
from Table A
where date = '2014-10-15' and Source = 'EMAIL'
group by date,source
There is no EMAIL source for a particular day. So, it gives no rows.
But I want to get 0 in Totalcount even if EMAIL is not there for that day but can present next day.
It should be like,
Date,Source, Totalcount
15/10/14,Email,0
I used ISNULL function not working as no rows has been resulted.

You could perform a join with a "constant" query. It's an ugly hack, but it should do the trick:
SELECT c.date, c.source, COALESCE(totalcount, 0)
FROM (SELECT '2014-10-15' AS date, 'EMAIL' AS source) c
LEFT JOIN (SELECT date, source, COUNT(*) AS totalcount
FROM a
GROUP BY date, source) a
ON a.date = c.date AND a.source = c.source

Related

How to return null values if there is no data to display in BigQuery [duplicate]

This question already has answers here:
Display default value if query results in no records in BigQuery
(2 answers)
Closed 10 months ago.
My question is I want to get null values when there is "no data to display" in the BigQuery.
like this:
But it only works when there are only aggregate functions. How to modify below query so that returns null values?
My query:
select oid, date, coalesce(sum(quantity_sold),0) as quantity_sold
from table
where oid = 'xxx' and (date >= 'xxx' and date <= 'xxx')
group by 1,2
I found this similar SO question but it creates a column that contains a message that says "Results not found" and assigns null values to other columns. You can apply this query and remove the message and retain only the null values, your query will look like this:
with sample_data as (
select 123 as oid, '2022-01-01' as date, 23 as quantity_sold
union all select 111 as oid, '2022-01-02' as date, 24 as quantity_sold
),
actual_query as (
select oid,date,coalesce(sum(quantity_sold),0) as quantity_sold
from sample_data
where oid = 534 and (date >= '2021-03-23' and date <= '2021-04-23')
group by 1,2
)
-- query below is the modified query from the linked SO question above
select actual_query.*
from actual_query
union all
select actual_query.* -- all the `actual_query` columns will be `NULL`
from (select 1) left join
actual_query
on 1 = 0 -- always false
where not exists (select 1 from actual_query);
Sample output:
NOTE: I created random values for sample data that could mimic the message "There is no data to display" when I ran your query.

How to check another column value to be the highest to determine the latest record that occurs multiple times in Oracle SQL Developer? [duplicate]

This question already has answers here:
Fetch the rows which have the Max value for a column for each distinct value of another column
(35 answers)
Select First Row of Every Group in sql [duplicate]
(2 answers)
Return row with the max value of one column per group [duplicate]
(3 answers)
Get value based on max of a different column grouped by another column [duplicate]
(1 answer)
SQL: getting the max value of one column and the corresponding other columns [duplicate]
(2 answers)
Closed 2 years ago.
I have a table called ro_main_table which stores details of productions such as serial_nr, pr_date_time, machine_nr, record_key etc. I would like to get the distinct machine_nr and record key from ro_main_table where pr_date_time is in last 6 hours. For this I do:
select machine_nr, record_key, pr_date_time from ro_main_table where pr_date_time >= SYSDATE - 6/24;
Which gives me the table below:
MACHINE_NR
RECORD_KEY
PR_DATE_TIME
54
9809
17-DEC-20 04.02.35.000000000 AM
55
9811
17-DEC-20 04.58.22.000000000 AM
55
9817
17-DEC-20 09.17.50.000000000 AM
54
9814
17-DEC-20 07.57.24.000000000 AM
50
9818
17-DEC-20 09.45.22.000000000 AM
However, as you see there might be machines which are started twice during this time (i.e. machine_nr occurs multiple times). If this is the case, I will choose the record which has the highest record_key. For example, for machine 55 it is 9817. How can I achieve this?
Thank you very much in advance!
select machine_nr, max(record_key), pr_date_time
from ro_main_table
where pr_date_time >= SYSDATE - 6/24
group by machine_nr;
this query should get the result you wish
I found a way. I create an inner join like this:
select tt.machine_nr, tt.record_key, tt.pr_date_time
from ro_main_table tt
INNER JOIN
(SELECT machine_nr, MAX(record_key) AS MaxRecordKey
FROM ro_main_table
GROUP BY machine_nr) groupedtt
ON tt.machine_nr = groupedtt.machine_nr
AND tt.record_key = groupedtt.MaxRecordKey
where pr_date_time >= SYSDATE - 6/24;
You can use the window function as follows:
select * from
(select machine_nr, record_key, pr_date_time
row_number() over (partition by machine_nr order by record_key desc) as rn
from ro_main_table where pr_date_time >= SYSDATE - 6/24)
where rn = 1;

Oracle SQL: Get the max record for each duplicate ID in self join table [duplicate]

This question already has answers here:
Fetch the rows which have the Max value for a column for each distinct value of another column
(35 answers)
GROUP BY with MAX(DATE) [duplicate]
(6 answers)
Oracle SQL query: Retrieve latest values per group based on time [duplicate]
(2 answers)
Closed 5 years ago.
It's been marked as a duplicate and seems to be explained a bit in the linked questions, but I'm still trying to get the separate DEBIT and CREDIT columns on the same row.
I've created a View and I am currently self joining it. I'm trying to get the max Header_ID for each date.
My SQL is currently:
SELECT DISTINCT
TAB1.id,
TAB1.glperiods_id,
MAX(TAB2.HEADER_ID),
TAB1.batch_date,
TAB1.debit,
TAB2.credit,
TAB1.descrip
FROM
IQMS.V_TEST_GLBATCH_GJ TAB1
LEFT OUTER JOIN
IQMS.V_TEST_GLBATCH_GJ TAB2
ON
TAB1.ID = TAB2.ID AND TAB1.BATCH_DATE = TAB2.BATCH_DATE AND TAB1.GLPERIODS_ID = TAB2.GLPERIODS_ID AND TAB1.DESCRIP = TAB2.DESCRIP AND TAB1.DEBIT <> TAB2.CREDIT
WHERE
TAB1.ACCT = '3648-00-0'
AND
TAB1.DESCRIP NOT LIKE '%INV%'
AND TAB1.DEBIT IS NOT NULL
GROUP BY
TAB1.id,
TAB1.glperiods_id,
TAB1.batch_date,
TAB1.debit,
TAB2.credit,
TAB1.descrip
ORDER BY TAB1.batch_date
And the output for this is (37 rows in total):
I'm joining the table onto itself to get DEBIT and CREDIT on the same line. How do I select only the rows with the max HEADER_ID per BATCH_DATE ?
Update
For #sagi
Those highlighted with the red box are the rows I want and the ones in blue would be the ones I'm filtering out.
Fixed mistake
I recently noticed I had joined my table onto itself without making sure TAB2 ACCT='3648-00-0'.
The corrected SQL is here:
SELECT DISTINCT
TAB1.id,
TAB1.glperiods_id,
Tab1.HEADER_ID,
TAB1.batch_date,
TAB1.debit,
TAB2.credit,
TAB1.descrip
FROM
IQMS.V_TEST_GLBATCH_GJ TAB1
LEFT OUTER JOIN
IQMS.V_TEST_GLBATCH_GJ TAB2
ON
TAB1.ID = TAB2.ID AND TAB1.BATCH_DATE = TAB2.BATCH_DATE AND TAB2.ACCT ='3648-00-0'AND TAB1.GLPERIODS_ID = TAB2.GLPERIODS_ID AND TAB1.DESCRIP = TAB2.DESCRIP AND TAB1.DEBIT <> TAB2.CREDIT
WHERE
TAB1.ACCT = '3648-00-0'
AND
TAB1.DESCRIP NOT LIKE '%INV%'
AND TAB1.DEBIT IS NOT NULL
ORDER BY TAB1.BATCH_DATE
Use window function like ROW_NUMBER() :
SELECT s.* FROM (
SELECT t.*,
ROW_NUMBER() OVER(PARTITION BY t.batch_id ORDER BY t.header_id DESC) as rnk
FROM YourTable t
WHERE t.ACCT = '3648-00-0'
AND t.DESCRIP NOT LIKE '%INV%'
AND t.DEBIT IS NOT NULL) s
WHERE s.rnk = 1
This is an analytic function that rank your record by the values provided in the OVER clause.
PARTITION - is the group
ORDER BY - Who's the first of this group (first gets 1, second 2, ETC)
It is a lot more efficient then joins(Your problem could have been solved in many ways) , and uses the table only once.

How to select the first row from group by date [duplicate]

This question already has answers here:
Select first row in each GROUP BY group?
(20 answers)
Closed 8 years ago.
I am writing a program for amateur radio. Some callsigns will appear more than once in the data but the qsodate will be different. I only want the first occurrence of a call sign after a given date.
The query
select distinct
a.callsign,
a.SKCC_Number,
a.qsodate,
b.name,
a.SPC,
a.Band
from qso a, skccdata b
where SKCC_Number like '%[CTS]%'
AND QSODate > = '2014-08-01'
and b.callsign = a.callsign
order by a.QSODate
The problem:
Because contacts occur on different dates, I get all of the contacts - I have tried adding min(a.qsodate) to get only the first but then I run into all sorts of issues regarding grouping.
This query will be in a stored procedure, so creating temp tables or cursors will not be a problem.
You can use the ROW_NUMBER() to get the first row with the first date, like this:
WITH CTE
AS
(
select
a.callsign,
a.SKCC_Number,
a.qsodate,
b.name,
a.SPC,
a.Band,
ROW_NUMBER() OVER(PARTITION BY a.callsign ORDER BY a.QSODate) AS RN
from qso a,skccdata b
where SKCC_Number like '%[CTS]%'
AND QSODate > = '2014-08-01'
and b.callsign = a.callsign
)
SELECT *
FROM CTE
WHERE RN = 1;
ROW_NUMBER() OVER(PARTITION BY a.callsign ORDER BY a.QSODate) will give you a ranking number for each group of callsign ordered by QSODate, then the WHERE RN = 1 will eliminate all the rows except the first one which has the minimum QSODate.
Have you tried starting your query with SELECT TOP 1 ...(fields) Then you will only get one row. You can use TOP x .... for x number of rows, or TOP 50 PERCENT for the top half of the rows, etc. Then you can eliminate DISTINCT in this case
EDIT: misunderstood question. How about this?
select
a.callsign,
a.SKCC_Number,
a.qsodate,
(SELECT TOP 1 b.name FROM skccdata b WHERE b.callsign = a.callsign) as NAME,
a.SPC,
a.Band
from qso a
where SKCC_Number like '%[CTS]%'
AND QSODate > = '2014-08-01'
GROUP BY a.QSODate, a.callsign, a.SKCC_Number, a.SPC, a.Band
order by a.QSODate
and add callsign to your where clause to isolate callsigns

Grouping two dates as one in Oracle-SQL

I have a table 'task' with three relevant fields: date_created, date_updated, and is_closed.
I have a simple query that counts the number of tasks created:
SELECT task.date_created, count(task.is_closed)
FROM task
GROUP BY task.date_created
ORDER BY task.date_created
What I'd like is to also have the number of tasks closed per day. For our purposes, a task's final updated date is when is_closed='true'
So, the final table should look like
date opened closed
04/01/13 8 6
04/02/13 9 5
I think you need to do this as two subqueries. Here is one approach, using full outer join:
select coalesce(a.date_created, c.date_updated) as thedate,
coalesce(a.opened, 0) as opened,
coalesce(c.closed, 0) as closed
from (select date_created, count(*) as opened
from task
group by date_created
) a full outer join
(select date_updated, count(*) as closed
from task
where is_closed = 1 -- or whatever the value is
group by date_updated
) c
on a.date_created = c.date_updated
The full outer join guarantees that all dates are present, even when you have only closes or opens.
You can use a CASE statement with your COUNT:
SELECT task.date_created,
count(1) opened,
count(case when is_closed = 'true' then 1 end) closed
FROM task
GROUP BY task.date_created
ORDER BY task.date_created
SQL Fiddle Demo
Given your comments, here is an approach using a couple Common Table Expressions:
WITH OPENED AS (
SELECT date_created, count(1) opened
FROM task
GROUP BY date_created
) ,
CLOSED AS (
SELECT date_updated, count(1) closed
FROM task
WHERE is_closed = 'true'
GROUP BY date_updated
)
SELECT D.YourDateField, o.opened, c.closed
FROM YourDateTable D
LEFT JOIN Opened O ON D.YourDateField = O.Date_Created
LEFT JOIN CLosed C ON D.YourDateField = C.Date_Created
As Gordon points out, a FULL OUTER JOIN would also work. I just prefer using a dates table to seed from. Create the table once, and use it wherever you may need to.