I have been tasked with converting an old reports program to Oracle reports and I came to a halt when I needed to join two queries to make the report work. I'm not new to SQL, but I do need help on this one.
For Oracle Reports 11g, reports needs to show the results of the following two queries, therefore, these queries need to be joined together in one single SQL query for the report to work.
First query:
select table_name
, to_char(load_date, 'MM/DD/ YYYY') as XDATE
, to_char(number_name) as NUMBER NAME
, round(sysdate-load_date) as DAYS
, 'E' AS TABLEIND
from error_table
where load_date is not null
and round(sysdate-load_date) > 15
and number_name not in
(select number_name
from table_comments)
order by table_name
Second query:
select table_name
, to_char(load_date, 'MM/DD/ YYYY') as XDATE
, to_char(number_name) as NUMBER NAME
, round(sysdate-load_date) as DAYS
, 'O' AS TABLEIND
from other_table
where load_date is not null
and round(sysdate-load_date) > 15
and number_name not in
(select number_name
from table_comments)
order by table_name
The results of these two queries should show the results of these two queries with the first query first, and the second query second. Any help with this problem is highly appreciated.
( Query1
--leave out the "order by" line
)
UNION ALL
( Query2
--leave out the "order by" line, too
)
ORDER BY TABLEIND
, table_name
If you're trying to get these to come out in one result set, try a UNION between them. You can order the whole result set by TABLEIND, table_name to sort the way you want, I believe.
You can create a union query with the existing queries as inline views:
select 1 as whichQuery, q1.col, q1.col, ...
from
(select....) as q1
union all
select 2 as whichQuery, q2.col, q2.col, ...
from
(select ....) as q2
and then you can order by whichQuery. That guarantees the order you want in case TABLEIND alpha sort value should vary (and not sort in the order you want).
If you HAVE to have it in this format dump the results of the first query into a temp table with an identity column then dump the results of the second query into the same table.
Then select from that temp table sorted off that identity column
Related
In this table there are three colum and in need the value for of data which are lesser than code = 28,this is my query
SELECT value,code,date
FROM table
order by date,vchcode
but when i ad where clouse like
SELECT value,code,date
FROM table
where code < 28
order by date,vchcode
is only shows 2 row with code 26 and 27... i need 26,27 and 32.. and table colums are variable its not fix..
I think you wnat to take the date into account -- what you really want are all rows before the date of the row with code 28.
One method uses a subquery:
SELECT t.value, t.code, t.date
FROM table t
WHERE date < (SELECT date FROM table t2 WHERE t2.code = 28)
ORDER BY t.date, t.vchcode
I am execute below query. there are no data but SQL Nevigator fetch ONE record and this record are show the blank. so i want no fetch any record.
select sum(arrears_edutax)
from view_govtax_rpt
where trunc(receiptdt) between '01-Oct-2019' and '14-Oct-2019';
But dont use Group BY function.
there are no data but SQL Nevigator fetch ONE record and this record are show the blank. so i want no fetch any record
That's not how aggregate queries work.
An aggregate query with no GROUP BY returns one row. The result is the aggregation applied to the filtered rows. Because you had no rows which matched your criteria the aggregated value is NULL. If you had used a COUNT() function instead you would have got zero.
So, if you really want an empty result set (zero rows) when there's no matching data you can use this trick:
select sum(arrears_edutax)
from view_govtax_rpt
where trunc(receiptdt) between date '2019-10-01' and date '2019-10-14'
having count(*) > 0
;
Incidentally, you should get into the habit of using date literals instead of relying on implicit data conversion.
Quick demonstration about what you need
with w0 as
(
select 1 x from dual union
select 2 from dual
), w1 as
(
select * from w0 where 1=2
)
select c1 from (
select sum(x) c1 from w1
)
where c1 is not null
Click here for demo
Try this query
select sum(null) c1 from dual where 1=2
No data due to 1=2 but one row result
Query:
SELECT *
FROM [MemberBackup].[dbo].[OriginalBackup]
where ration_card_id in
(
1247881,174772,
808454,2326154
)
Right now the data is ordered by the auto id or whatever clause I'm passing in order by.
But I want the data to come in sequential format as per id's I have passed
Expected Output:
All Data for 1247881
All Data for 174772
All Data for 808454
All Data for 2326154
Note:
Number of Id's to be passed will 300 000
One option would be to create a CTE containing the ration_card_id values and the orders which you are imposing, and the join to this table:
WITH cte AS (
SELECT 1247881 AS ration_card_id, 1 AS position
UNION ALL
SELECT 174772, 2
UNION ALL
SELECT 808454, 3
UNION ALL
SELECT 2326154, 4
)
SELECT t1.*
FROM [MemberBackup].[dbo].[OriginalBackup] t1
INNER JOIN cte t2
ON t1.ration_card_id = t2.ration_card_id
ORDER BY t2.position DESC
Edit:
If you have many IDs, then neither the answer above nor the answer given using a CASE expression will suffice. In this case, your best bet would be to load the list of IDs into a table, containing an auto increment ID column. Then, each number would be labelled with a position as its record is being loaded into your database. After this, you can join as I have done above.
If the desired order does not reflect a sequential ordering of some preexisting data, you will have to specify the ordering yourself. One way to do this is with a case statement:
SELECT *
FROM [MemberBackup].[dbo].[OriginalBackup]
where ration_card_id in
(
1247881,174772,
808454,2326154
)
ORDER BY CASE ration_card_id
WHEN 1247881 THEN 0
WHEN 174772 THEN 1
WHEN 808454 THEN 2
WHEN 2326154 THEN 3
END
Stating the obvious but note that this ordering most likely is not represented by any indexes, and will therefore not be indexed.
Insert your ration_card_id's in #temp table with one identity column.
Re-write your sql query as:
SELECT a.*
FROM [MemberBackup].[dbo].[OriginalBackup] a
JOIN #temps b
on a.ration_card_id = b.ration_card_id
order by b.id
I'll do my best to summarize what I am having trouble with. I never used much SQL until recently.
Currently I am using SQL Server 2012 at work and have been tasked with trying to find oddities in SQL tables. Specifically, the tables contain similar information regarding servers. Kind of meta, I know. So they each share a column called "DB_NAME". After that, there are no similar columns. So I need to compare Table A and Table B and produce a list of records (servers) where a server is NOT listed in BOTH Table A and B. Additionally, this query is being ran against an exception list. I'm not 100% sure of the logic to best handle this. And while I would love to get something "extremely efficient", I am more-so looking at something that just plain works at the time being.
SELECT *
FROM (SELECT
UPPER(ta.DB_NAME) AS [DB_Name]
FROM
[CMS].[dbo].[TABLE_A] AS ta
UNION
SELECT
UPPER(tb.DB_NAME) AS [DB_Name]
FROM
[CMS].[dbo].[TABLE_B] as tb
) AS SQLresults
WHERE NOT EXISTS (
SELECT *
FROM
[CMS].[dbo].[TABLE_C_EXCEPTIONS] as tc
WHERE
SQLresults.[DB_Name] = tc.DB_NAME)
ORDER BY SQLresults.[DB_Name]
One method uses union all and aggregation:
select ab.*
from ((select upper(name) as name, 'A' as which
from CMS.dbo.TABLE_A
) union all
(select upper(name), 'B' as which
from CMS.dbo.TABLE_B
)
) ab
where not exists (select 1
from CMS.dbo.TABLE_C_EXCEPTION e
where upper(e.name) = ab.name
)
having count(distinct which) <> 2;
SQL Server is case-insensitive by default. I left the upper()s in the query in case your installation is case sensitive.
Here is another option using EXCEPT. I added a group by in each half of the union because it was not clear in your original post if DB_NAME is unique in your tables.
select DatabaseName
from
(
SELECT UPPER(ta.DB_NAME) AS DatabaseName
FROM [CMS].[dbo].[TABLE_A] AS ta
GROUP BY UPPER(ta.DB_NAME)
UNION ALL
SELECT UPPER(tb.DB_NAME) AS DatabaseName
FROM [CMS].[dbo].[TABLE_B] as tb
GROUP BY UPPER(tb.DB_NAME)
) x
group by DatabaseName
having count(*) < 2
EXCEPT
(
select DN_Name
from CMS.dbo.TABLE_C_EXCEPTION
)
I m selecting data from two different tables with no matching columns using this sql query
select * from (SELECT s.shout_id, s.user_id, s.time FROM shouts s
union all
select v.post_id, v.sender_user_id, v.time from void_post v)
as derived_table order by time desc;
Now is there any other way or with this sql statement only can i
differentiate the data from the two tables.
I was thinking of a dummy row that can be created at run-time(in the select statement only ) which would flag the row from the either tables.
As there is no way i can differentiate the shout_id that is thrown in the unioned table is
shout_id from the shout table or from the void_post table.
Thanks
Pradyut
You can just include an extra column in each select (I'd suggest a BIT)
select * from
(SELECT s.shout_id, s.user_id, s.time, 1 AS FromShouts FROM shouts s
union all
select v.post_id, v.sender_user_id, v.time, 0 AS FromShouts from void_post v)
as derived_table order by time desc;
Sure, just add a new field in your select statement called something like source with a different constant value for each source.
SELECT s.shout_id, s.user_id, s.time, 'shouts' as source FROM shouts s
UNION ALL
SELECT v.post_id, v.sender_user_id, v.time, 'void_post' as source FROM void_post v
A dummy variable is a nice way to do it. There isn't much overhead in the grand scheme of things.
p.s., the dummy variable represents a column and not a row.