Join 2 Queries and a Pivot in SQL - sql

I have 2 queries that I want to join together. They come from the same table, but the organization and structure of columns is bad. Hence the need for a Pivot in Query 1, then join it to Query 2.
I do know that this needs to be done with a CTE, but my output either results in a blank query, or info in the wrong columns.
I'm using SSMS18. Thanks for the help.
Query 1
Select *, '' AS 'DNC', '' AS 'DNF', '' AS 'DNR' from
(Select
Opin,
Qty,
[TicketDate],
[TicketNumber],
[Cust],
[ProdID]
from [dbo].[obser]) AS ID
Pivot (
SUM([Qty])
For [Opin] IN ([ArvUnits],[DeliveryUnits])
) AS SingleOTRow
where
TicketDate between '2021-01-01' and '2021-03-15'
and ProdID like '%_LB%'
Query 2
select
IOA.Cust, IOA.TicketNumber, IOA.TicketDate, '' AS 'ProdID','' AS 'IOA QTY', '' AS 'Delivery Units', IOA.ProdID AS 'DNC',
case
When IOA.Qty >=1 Then '1'
else 'N'
end AS 'DNF',
CASE
when IOA.ProdID = '21' Then 'Full'
else 'Not a Valid DNC- Review'
END as 'DNR'
from [dbo].[obser] AS IOA
where
IOA.TicketDate between '2021-01-01' and '2021-03-15' and
IOA.Opin= 'DNS'
Sample Data
[Sample Data]

Related

How to check unique values in SQL

I have a table named Bank that contains a Bank_Values column. I need a calculated Bank_Value_Unique column to shows whether each Bank_Value exists somewhere else in the table (i.e. whether its count is greater than 1).
I prepared this query, but it does not work. Could anyone help me with this and/or modify this query?
SELECT
CASE
WHEN NULLIF(LTRIM(RTRIM(Bank_Value)), '') =
(SELECT Bank_Value
FROM [Bank]
GROUP BY Bank_Value
HAVING COUNT(*) = 1)
THEN '0' ELSE '1'
END AS Bank_Key_Unique
FROM [Bank]
A windowed count should work:
SELECT
*,
CASE
COUNT(*) OVER (PARTITION BY Bank_Value)
WHEN 1 THEN 1 ELSE 0
END AS Bank_Value_Unique
FROM
Bank
;
It works also, but I found solution also:
select CASE WHEN NULLIF(LTRIM(RTRIM(Bank_Value)),'') =
(select Bank_Value
from Bank
group by Bank_Value
having (count(distinct Bank_Value) > 2 )) THEN '1' ELSE '0' END AS
Bank_Value_Uniquness
from Bank
It was missing "distinct" in having part.

How to return 'blank' using Sum function in Sql, if Sum is resulting 0 in SQL

I am using Sql Server 2008. I am adding some column value using Sum function. Like the code below:
SELECT 'RCOAuthorizer LMS',
'' AS Consumer_Loan,
'' AS Auto_Loan,
'' AS Credit_Card,
SUM(CASE
WHEN sq2.loan_type = 'Loan Amendment' THEN sq2.user_count
ELSE ''
END ) AS Loan_Amendment,
SUM(CASE
WHEN sq2.loan_type = 'Pre-Payment' THEN sq2.user_count
ELSE ''
END ) AS Pre_Payment,
SUM(CASE
WHEN sq2.loan_type = 'Corporate Credit card' THEN sq2.user_count
ELSE ''
END ) AS Corporate_Credit_card,
'' AS Auto_Payment_Release,
'' AS Car_Mulkiya
FROM
( SELECT 'RCOAuthorizer' AS ws_name,
'Loan Amendment' AS loan_type,
COUNT (DISTINCT a.bpm_referenceno) AS user_count,
a.user_id AS user_id
FROM BM_LMS_DecisionHistoryGrid a
INNER JOIN
( SELECT m.bpm_referenceno
FROM BM_LMS_EXTTABLE m
WHERE m.request_type = 'Loan Amendment' ) sq1 ON a.bpm_referenceno = sq1.bpm_referenceno
WHERE workstep_name = 'RCOAuthorizer'
GROUP BY a.user_id
UNION SELECT 'RCOAuthorizer',
'Pre-Payment',
COUNT (DISTINCT a.bpm_referenceno), a.user_id
FROM BM_LMS_DecisionHistoryGrid a
INNER JOIN
( SELECT m.bpm_referenceno
FROM BM_LMS_EXTTABLE m
WHERE m.request_type = 'Pre-Payment' ) sq1 ON a.bpm_referenceno = sq1.bpm_referenceno
WHERE workstep_name = 'RCOAuthorizer'
GROUP BY a.user_id
UNION SELECT 'RCOAuthorizer',
'Corporate Credit card',
COUNT (DISTINCT a.bpm_referenceno), a.user_id
FROM BM_LMS_DecisionHistoryGrid a
INNER JOIN
( SELECT m.bpm_referenceno
FROM BM_LMS_EXTTABLE m
WHERE m.request_type = 'Corporate Credit card' ) sq1 ON a.bpm_referenceno = sq1.bpm_referenceno
WHERE workstep_name = 'RCOAuthorizer'
GROUP BY a.user_id ) sq2
GROUP BY sq2.ws_name
The above query will return Sum of all the numbers available in 'a' column. But in case, there is no record, then it will return '0' as result.
I require that if there is no record, it must show blank instead of showing '0'. How to handle the same.
To start, you don't need an ISNULL with a back value of 0 (the neutral for adding) inside a SUM aggregate, as the SUM already ignores NULL values. So SUM(ISNULL(Column, 0)) is equal to SUM(Column) (but different from ISNULL(SUM(Column), 0)!).
Seems that you want a VARCHAR result instead of a numeric one. You can solve this with a CASE.
Select
CASE WHEN Sum(a) = 0 THEN '' ELSE CONVERT(VARCHAR(100), Sum(a)) END
from
table;
If you don't want to repeat the SUM expression:
;WITH SumResult AS
(
Select CONVERT(VARCHAR(100), Sum(a)) AS SumTotal
from table
)
SELECT
CASE WHEN R.SumTotal = '0' THEN '' ELSE R.SumTotal END
FROM
SumResult AS R
Keep in mind that in these both cases, if there is no record to calculate the sum from, the result will be NULL.
EDIT: There is no point in adding '' inside your SUM, as it's converted to 0 to be able to sum. The solution is still the same as I posted before.
Change
SUM(CASE
WHEN sq2.loan_type = 'Pre-Payment' THEN sq2.user_count
ELSE ''
END ) AS Pre_Payment,
for
CASE
WHEN SUM(CASE WHEN sq2.loan_type = 'Pre-Payment' THEN sq2.user_count END) = 0 THEN ''
ELSE CONVERT(VARCHAR(100), SUM(CASE WHEN sq2.loan_type = 'Pre-Payment' THEN sq2.user_count)) END AS Pre_Payment,
Just try this ( use isnull again ):
Select isnull(Sum(isnull(a,0)),0) from table_;
I used table_ instead of table, because table is a reserved keyword.
SQL Fiddle Demo

Joining a Temp Table to Actual Table

I need to verify that each order has been acknowledged. The problem is that each order can have multiple codes. The query I had (utilizing a CASE statement) would check for blank fields or fields with the string "None" to verify the order has not been acknowledged. It would return the appropriate result, but multiple rows (once for each possible response) and I only need (1).
I'm attempting to create a temp table that will return the appropriate result and join (via an order unique ID) the two tables together hoping to correct the multiple row issue. Here is the code:
DROP TABLE staging_TABLE;
CREATE TEMP TABLE staging_TABLE(
ORDERID varchar(256) ,
CODE varchar(256) );
/*Keeping data types consistent with the real table*/
INSERT INTO staging_TABLE
SELECT ORDERID,
CASE CODE
WHEN 'None' THEN 'No'
WHEN '' THEN 'No'
ELSE 'Yes'
END
FROM ORDERS
WHERE UTCDATE > SYSDATE - 10
AND CODE IS NOT NULL;
SELECT R.QUESTION,
R.ORDERNAME,
T.CODE
FROM ORDERS R
INNER JOIN staging_TABLE T
ON R.ORDERID= T.ORDERID
WHERE R.UTCDATE > SYSDATE - 10
AND R.CODE IS NOT NULL
AND R.CATEGORY IS NOT NULL
AND R.UTCDATE IS NOT NULL
GROUP BY
R.ORDER,
T.CODE,
R.ORDERNAME,
R.CODE
ORDER BY
R.ORDERNAME,
R.ORDER;
Am I doing this correctly? Or is this even the right approach?
Am I doing this correctly? Or is this even the right approach?
No. You don't need a temp table for this. Your query might look like this:
SELECT question, ordername
, CASE WHEN code IN ('None', '') THEN 'No' ELSE 'Yes' END AS code
FROM orders
WHERE utcdate > sysdate - 10
AND code IS NOT NULL
AND category IS NOT NULL
GROUP BY question, ordername, 3, "order"
ORDER BY ordername, "order";
ORDER is a reserved word. It's not possible to use it as column name unless double quoted. There is something wrong there.
AND R.UTCDATE IS NOT NULL is redundant. It can't be NULL anyway with WHERE R.UTCDATE > SYSDATE - 10
3 in my GROUP BY clause is a positional reference to the CASE expression. Alternatively you can spell it out again:
....
GROUP BY question, ordername
, CASE WHEN code IN ('None', '') THEN 'No' ELSE 'Yes' END
, "order"
You can use the DISTINCT keyword as follows so you will not need a temp table:
SELECT DISTINCT QUESTION,
ORDERNAME,
CASE CODE
WHEN 'None' THEN 'No'
WHEN '' THEN 'No'
ELSE 'Yes'
FROM ORDERS
WHERE UTCDATE > SYSDATE - 10
AND CODE IS NOT NULL
AND CATEGORY IS NOT NULL
AND UTCDATE IS NOT NULL
ORDER BY 2,3;

SQL to 'group' certain records

I am not entirely sure if this is possible in SQL (I am by no means an expert).
I have lines of data in TABLEA like below:
I wish to have an SQL output that will 'group' any records together that where Activity!=D. The output results would need look like the table below:
Any 'merged' activities would would be grouped as 'Merged'. In the example, this would be A and B.
I got started
select
cycle_start,
cycle_end,
activity_start,
activity_end,
case when (Activity="D") then "D" else "Merged" end
but then I struggle to get the aggregation correct
Yes, you can do this with a case in the group by:
select cycle_start, cycle_end,
min(activity_start) as activity_start,
max(activity_end) as activity_end,
(case when Activity = 'D' then 'D' else 'Merged' end)
from table t
group by cycle_start, cycle_end,
(case when Activity = 'D' then 'D' else 'Merged' end)

I want to write a summary query and present the results in a single table

I need to write a summary report on 3 different status values, with a count and an amount column for each status, with the results presented in a single table. For example, the output would look like this:
The query to produce each line of code (in an individual output) is:
select case when status_key = '2' then 'Paid' else '' end as 'Status'
, COUNT(BillNo) as [Count]
, SUM(amtpd) as [Amount Paid]
from billtable
where client = 101
and status_key = '2'
group by status_key
select case when status_key = '1' then 'Queued' else '' end as 'Status'
, COUNT(BillNo) as [Count]
, SUM(amtpd) as [Amount Paid]
from billtable
where client = 101
and status_key = '1'
group by status_key
select case when status_key = '4' then 'Hold' else '' end as 'Status'
, COUNT(BillNo) as [Count]
, SUM(amtpd) as [Amount Paid]
from billtable
where client = 101
and status_key = '4'
group by status_key
This produces three results like:
I am using SQL Server database and SSMS to develop the query.
No need for union.
Use WHERE to filter to only the status_keys that you want, then expand you CASE statement to re-code from a number to a word.
select
case when status_key = '2' then 'Paid'
when status_key = '1' then 'Queued'
when status_key = '4' then 'Hold'
else 'Error!' end AS [Status],
COUNT(BillNo) AS [Count],
SUM(amtpd) AS [Amount Paid]
from
billtable
where
client = 101
AND status_key IN ('1','2','4')
group by
status_key
EDIT Modified example using a dimension table
select
status.description AS [Status],
COUNT(bill_table.BillNo) AS [Count],
SUM(bill_table.amtpd) AS [Amount Paid]
from
billtable
inner join
status
on billtable.status_key = status.key
where
bill_table.client = 101
AND bill_table.status_key IN ('1','2','4')
group by
status.description
You can then have a foreign key constraint from status to billtable. This will ensure that data can not be inserted into billtable unless there is a corresponding key in status.
Your lookups will then always work. But at the 'cost' of inserts failing if the status table has not been correctly populated.
This fact-table and dimension-table construction is the underpinning of relational database design.
you just have to union all
your first query
Union all
your Second query
union all
your third query
Just add UNION between your queries.