SELECT id,
login_id,
count,
case when count = 0 then 'Cat_A'
WHEN count between 1 and 10 then 'Cat_B'
WHEN count > 10 then 'Cat_C'
WHEN count IS NULL THEN 'Cat D'
END as Category
FROM
(
select id,login_id,min(ord_count) AS count
FROM table_1 X
JOIN table_2 Y
ON X.id_col = Y.id_col
WHERE date = '2022-02-02'
AND login_id = 'True'
group by id,login_id
)A
LEFT JOIN
(
SELECT id,COUNT(X.ord_no) AS count_of_orders
FROM table_1 X
WHERE X.date = '2022-02-02'
group by id
)B
ON A.id=B.id
When I join these two tables, I'm getting NULL values for the unmatched records.
I need to replace those NULL records to some hardcoded value say 'XYZ'.
Any guidance on how to achieve this please?
So the top level select needs to name which ID it is using (other DB's don't require this snowflake does), given you are selecting from A and b.id might be missing, it should be a.id
count_of_orders is not used, so currently the LEFT JOIN to B is pointless, given your question is about LEFT JOIN this must be the column you a referring to??
The replace NULL values can be done via COALESCE or NVL or ZEROIFNULL, given the only null thing is a count, zeroifnull seems to make sense here.
which all make me think your SQL needs to look like:
SELECT
a.id,
a.login_id,
a.count,
case
WHEN a.count = 0 then 'Cat_A'
WHEN a.count between 1 and 10 then 'Cat_B'
WHEN a.count > 10 then 'Cat_C'
WHEN a.count IS NULL THEN 'Cat D'
END as Category,
ZEROIFNULL(b.count_of_orders) as count_of_orders
FROM (
SELECT
id,
login_id,
min(ord_count) AS count
FROM table_1 AS X
JOIN table_2 AS Y
ON X.id_col = Y.id_col
WHERE date = '2022-02-02'
AND login_id = 'True'
group by id,login_id
) as A
LEFT JOIN (
SELECT
x.id,
COUNT(X.ord_no) AS count_of_orders
FROM table_1 as X
WHERE X.date = '2022-02-02'
group by x.id
)as B
ON A.id=B.id
The A sub-select really should use the aliases you named X, Y so we know which tables id, login_id, ord_count, & date all come from.
Related
I am trying to obtain two different counts in a query. One count would be the count of the specific item in one table, and the other count would be the same but from a different table. I can write 2 different queries that provides me the info but in two different tables. I would like to write one query that puts it all into one table. Thank you guys for any of suggestions.
EDIT: To clarify, I would like to add the count from the second query to a column on the first query.
My query
select d.description, count(item_id) from productdetails pd
join inventory i on i.itemnum=pd.item_id
join departments d on d.dept_id=i.dept_id
where i.last_sold is not null and in_stock !=0
group by d.description
select d.description, count(itemnum)
from inventory i
join departments d on d.dept_id=i.dept_id
where in_stock != 0 and last_sold is not null
group by d.description
Place your queries in a sub-query where each count has been established and the "missing" count is assigned a value of zero.
Next, sum the count.
SELECT smmry.description
, SUM(smmry.pd_item_cnt) pd_item_cnt
, SUM(smmry.itemnum_cnt) itemnum_cnt
FROM (
SELECT d.description
, COUNT(pd.item_id) pd_item_cnt
, 0 itemnum_cnt
FROM productdetails pd
JOIN inventory i
ON i.itemnum = pd.item_id
JOIN departments d
ON d.dept_id = i.dept_id
WHERE i.last_sold IS NOT NULL
AND in_stock != 0
GROUP BY d.description
UNION ALL
SELECT d.description
, 0 pd_item_cnt
, COUNT(i.itemnum) itemnum_cnt
FROM inventory i
JOIN departments d
ON d.dept_id = i.dept_id
WHERE in_stock != 0
AND last_sold IS NOT NULL
GROUP BY d.description
) smmry
GROUP BY smmry.description
WITH Query1 (Description1, Count1) AS (
select d.description, count(item_id) from productdetails pd
join inventory i on i.itemnum=pd.item_id
join departments d on d.dept_id=i.dept_id
where i.last_sold is not null and in_stock !=0
group by d.description
),
Query2 (Description2, Count2) AS (
select d.description, count(itemnum)
from inventory i
join departments d on d.dept_id=i.dept_id
where in_stock != 0 and last_sold is not null
group by d.description
)
SELECT Description1, Count1, Description2, Count2 FROM Query1, Query2
By running the following query I realized that I have duplicates on the column QueryExecutionId.
SELECT DISTINCT qe.QueryExecutionid AS QueryExecutionId,
wfi.workflowdefinitionid AS FlowId,
qe.publishing_date AS [Date],
c.typename AS [Type],
c.name As Name
INTO #Send
FROM
[QueryExecutions] qe
JOIN [Campaign] c ON qe.target_campaign_id = c.campaignid
LEFT JOIN [WorkflowInstanceCampaignActivities] wfica ON wfica.queryexecutionresultid = qe.executionresultid
LEFT JOIN [WorkflowInstances] wfi ON wfica.workflowinstanceid = wfi.workflowinstanceid
WHERE qe.[customer_idhash] IS NOT NULL;
E.g. When I test with one of these QueryExecutionIds, I can two results
select * from ##Send
where QueryExecutionId = 169237
We realized the reason is that these two rows have a different FlowId (second returned value in the first query). After discussing this issue, we decided to take the record with a FlowId that has the latest date. This date is a column called lastexecutiontime that sits in the third joined table [WorkflowInstances] which is also the table where FlowId comes from.
How do I only get unique values of QueryExecutionId with the latest value of WorkflowInstances.lastexecution time and remove the duplicates?
You can use a derived table with first_value partitioned by workflowinstanceid ordered by lastexecutiontime desc:
SELECT DISTINCT qe.QueryExecutionid AS QueryExecutionId,
wfi.FlowId,
qe.publishing_date AS [Date],
c.typename AS [Type],
c.name As Name
INTO #Send
FROM
[QueryExecutions] qe
JOIN [Campaign] c ON qe.target_campaign_id = c.campaignid
LEFT JOIN [WorkflowInstanceCampaignActivities] wfica ON wfica.queryexecutionresultid = qe.executionresultid
LEFT JOIN
(
SELECT DISTINCT workflowinstanceid, FIRST_VALUE(workflowdefinitionid) OVER(PARTITION BY workflowinstanceid ORDER BY lastexecutiontime DESC) As FlowId
FROM [WorkflowInstances]
) wfi ON wfica.workflowinstanceid = wfi.workflowinstanceid
WHERE qe.[customer_idhash] IS NOT NULL;
Please note that your distinct query is pertaining to the selected variables,
eg. Data 1 (QueryExecutionId = 169237 and typename = test 1)
Data 2 (QueryExecutionId = 169237 and typename = test 2)
The above 2 data are considered as distinct
Try partition by and selection the [seq] = 1 (the below code are partition by their date)
SELECT *
into #Send
FROM
(
SELECT *,ROW_NUMBER() OVER (PARTITION BY [QueryExecutionid] ORDER BY [Date] DESC) [Seq]
FROM
(
SELECT qe.QueryExecutionid AS QueryExecutionId,
wfi.FlowId,
qe.publishing_date AS [Date], --should not have any null values
qe.[customer_idhash]
c.typename AS [Type],
c.name As Name
FROM [QueryExecutions] qe
JOIN [Campaign] c
ON qe.target_campaign_id = c.campaignid
LEFT JOIN [WorkflowInstanceCampaignActivities] wfica
ON wfica.queryexecutionresultid = qe.executionresultid
LEFT JOIN
(
SELECT DISTINCT workflowinstanceid, FIRST_VALUE(workflowdefinitionid) OVER(PARTITION BY workflowinstanceid ORDER BY lastexecutiontime DESC) As FlowId
FROM [WorkflowInstances]
) wfi ON wfica.workflowinstanceid = wfi.workflowinstanceid
) a
WHERE [customer_idhash] IS NOT NULL
) b
WHERE [Seq] = 1
ORDER BY [QueryExecutionid]
I'm new with SQL and I need your help.
I have a table with a Name column and a Value column.
This value represents a 3-values enum, let's say Yes, No, and Maybe.
I'm trying to count, for each name, how many times I have each value of the enum. Something like this:
Name1 Yes 3
Name1 No 1
Name1 Maybe 4
Name2 Yes 0
Name2 No 1
Name2 Maybe 2
Name3 Yes 1
Name3 No 0
Name3 Maybe 7
but there are times when I don't have any entry for a given name with a given value, and it doesn't show up. Shortly, when count is 0, I don't get the row.
And I have to put it in a stored procedure.
How can I achieve this?
Thank you all in advance!
P.S. I'm using SQL Server
EDIT:
What I tried is:
SELECT Name,
Value,
COUNT(Value) as ValueCount
from Data
group by Name, Value
order by Name
Use a cross join to generate all the rows. Then use a left join to join in the values for counting:
SELECT n.Name, v.value, COUNT(d.value) as ValueCount
from (select distinct name from Data) n cross join
(select distinct value from Data) v left join
data d
on d.name = n.name and d.value = v.value
group by n.Name, v.Value
order by n.Name;
You don't specify the database. This is standard SQL and should work in any database.
You can use two cte to get a list of all combinations you want to show, then do a left join with your original table.
WITH enum AS
(
SELECT 'Yes' AS Value
UNION
SELECT 'No'
UNION
SELECT 'Maybe'
), combs AS
(
SELECT DISTINCT d.Name, e.Value
FROM enum e, Data d
)
SELECT c.Name, c.Value, COUNT(d.Name) FROM combs c
LEFT JOIN data d ON d.Name = c.Name AND d.Value = c.Value
GROUP BY c.Name, c.Value
ORDER BY c.Name, c.Value
Looking at your table overall, it would be a lot cleaner like this:
Name Yes No Maybe
__________________________
Bob 3 4 0
Tim 0 1 3
Jim 2 7 2
I know that's not really an answer to solving your problems but this table is much smaller and achieves the same results.
Often when trying to count something that isn't there, it's best to join to a driver table, in this case, you need all name/value pairs to join against, created below in a simple cte using a CROSS JOIN, but you could pull the values in a number of ways:
;with cte AS (SELECT DISTINCT d1.name,d2.value
FROM data d1
CROSS JOIN data d2
)
SELECT cte.Name,
cte.Value,
COALESCE(COUNT(d.Value),0) as ValueCount
from cte
LEFT JOIN Data d
ON d.value = cte.value
AND d.name = cte.name
group by cte.Name, cte.Value
order by cte.Name
Since this requires a LEFT JOIN any missing values will return NULL, so COALESCE() is used to show 0.
The DB I'm working with has the following 2 tables:
tblGroup
GroupId
GroupName
OtherGroupField, etc.
tblParts
PartId
PartNumber
GroupId
Price
OtherPartField, etc.
In my query I'd like to get the GroupId(s) which aren't in tblParts for a specified PartNumber
You can use the NOT IN predicate like this:
SELECT *
FROM tblGroups
WHERE GroupId NOT IN
(
SELECT GroupId
FROM tblParts
WHERE PartNumber = 'Some number'
AND GroupId IS NOT NULL
)
I would use an EXISTS with a join, rather than IN for better performance.
SELECT *
FROM tblGroups G
WHERE 1=1
And Not Exists
(
SELECT 1
FROM tblParts P
WHERE 1=1
And G.GroupId = P.GroupId
And PartNumber = 'PartNumberGoesHere'
)
My preference is EXCEPT
select GroupId from tblGroup
except
select GroupId from tblParts where PartNumber = 22
Its a little cleaner syntactically than outer joins even with a single item, but you can also use it to compare whole rows, e.g. looking for all rows of {A,B,C} that exist in table1 but not table2:
select A, B, C from table1
except
select A, B, C from table2
try with this
SELECT *
FROM tblGroups G
LEFT OUTER JOIN tblParts P ON P.GroupId=G.GroupId
WHERE P.PartId IS NULL
Tbl_cdr(ano,starttime)
Tbl_User(id,mobileno)
I want to count the rows from Tbl_cdr with condition omitting the rows (when ano = mobileno) and group by starttime.
any help ,Plz...
select c.starttime, count(*)
from Tbl_cdr c
where not exists (select 1 from Tbl_User u where u.mobileno = c.ano)
group by c.starttime
select count(*), c.StartTime
from Tbl_cdr c
left join Tbl_User u on c.ano = u.mobileno
where u.id is null
group by c.StartTime