I have a query structured like below, it checks if any of the entry in a given column is not null, if it finds a match (a value that is not null) it immediately returns Y, if all values are null it returns N. It works with a column called first_name but I need to make it work for other columns as well i.e last_name, middle_name, preferably all in a single query to save execution time. Y or N must be returned for each of the columns specified.
SELECT CASE
WHEN EXISTS(SELECT *
FROM (patient AS p JOIN patient_score AS s ON p.patient_id=s.patient_id)
WHERE first_name IS NOT NULL)
THEN 'Y'
ELSE 'N'
END AS your_result
I have another query which is an alternative and does the same job (1/0 instead of Y/N). But I don't know how to make it work with multiple columns either. A procedure that could work by supplying multiple column names would work as well.
SELECT COUNT(*) AS fn FROM
(SELECT 1
FROM (patient AS p JOIN patient_score AS s ON p.patient_id=s.patient_id)
WHERE first_name IS NOT NULL
LIMIT 1) AS T;
I think it is the query that you want, you have to add a SELECT element (CASE WHEN SUM(CASE WHEN column_name IS NULL THEN 0 ELSE 1 END) > 0 THEN 'Y' ELSE 'N' END AS column_name) for each column you want to check.
SELECT
CASE WHEN SUM(CASE WHEN first_name IS NULL THEN 0 ELSE 1 END) > 0 THEN 'Y' ELSE 'N' END AS first_name
FROM patient AS p
INNER JOIN patient_score AS s ON p.patient_id = s.patient_id
Related
I have data with column name Rule1 with values ..Correct, Incorrect and Undefined
I was able to get the count of them in this particular column using Group BY
select Rule1, count(*) from table_name group by Rule1;
I have one more column Rule2 with Values Correct, Incorrect only
When I try a similar select statement as above, I am getting the only count of Correct and Incorrect
I want to get the count of Undefined as zero as no Undefined is present in Rule2 column
How to do that
How I can write a query that needs to show the count of fixed values in multiple columns
You can create a derived table that enumerates the possible values with union all, then bring your table with a left join:
select x.rule1, count(t.rule1) cnt
from (select 'Correct' rule1 union all select 'Incorrect' union all select 'Undefined') x
left join mytable t on t.rule1 = x.rule1
group by x.rule1
This is a cross-database syntax that will work in both MySQL and SQL Server.
In very recent versions of MySQL, you can use the values(row ...) syntax:
select x.rule1, count(t.rule1) cnt
from (values row('Correct'), row('Incorrect'), row('Undefined')) x(rule1)
left join mytable t on t.rule1 = x.rule1
group by x.rule1
In SQL Server, the equivalent query is:
select x.rule1, count(t.rule1) cnt
from (values ('Correct'), ('Incorrect'), ('Undefined')) x(rule1)
left join mytable t on t.rule1 = x.rule1
group by x.rule1
You could also use sum like this:
SELECT
sum(case when Rule1 = 'Correct' then 1 else 0 end) AS Rule1Correct,
sum(case when Rule1 = 'Incorrect' then 1 else 0 end) AS Rule1Incorrect,
sum(case when Rule1 = 'Undefined' then 1 else 0 end) AS Rule1Undefined,
sum(case when Rule2 = 'Correct' then 1 else 0 end) AS Rule2Correct,
sum(case when Rule2 = 'Incorrect' then 1 else 0 end) AS Rule2Incorrect
FROM
table_name
WHERE
1
It enables multiple counts in one query. I added all the counts, thought the first two was enough for the idea.
Futhermore I have no idea what is better for the serverload, this or using unions.
Is there a way to rewrite this query without getting error?: Subquery returned more than 1 value.
This is query is used in a LEFT JOIN in a table-valued function. Per requirement, I need to by default pull two scenario IDs (if parameter value is NULL or empty)
DECLARE #pScenarioName AS VARCHAR(30)
select
externalID,
PropertyAssetId,
LeaseID,
BeginDate
from ae11.dbo.ivw_Leases
WHERE PropertyAssetID IN
(select ID from AE11.dbo.PropertyAssets where scenarioID IN
(CASE WHEN isnull(#pScenarioName, '') = ''
THEN (select top 2 ID from rvw_Scenarios where Name like '[0-9][0-9][0-9][0-9]%'
AND LEN(Name) = 8
order by Name desc)
ELSE
(select ID from aex.dbo.rvw_Scenarios
where [Name] IN (#pScenarioName))
END)
)
I haven't tested this, but I use a similar approach when dealing with parameters. Of course, this won't necessarily work if the order of the ID is crucial in your second subquery.
SELECT ExternalID
,PropertyAssetId
,LeaseID
,BeginDate
FROM ae11.dbo.ivw_Leases
WHERE PropertyAssetID IN
(SELECT ID
FROM AE11.dbo.PropertyAssets
WHERE scenarioID IN
(SELECT TOP 2 ID
FROM rvw_Scenarios
WHERE (#ISNULL(#pScenarioName,'') = ''
AND Name LIKE '[0-9][0-9][0-9][0-9]%'
AND LEN(Name) = 8)
ORDER BY Name DESC
UNION ALL
SELECT ID FROM aex.dbo.rvw_Scenarios
WHERE (#pScenarioName IS NOT NULL)
AND [Name] IN (#pScenarioName)))
I hope i word this out in a way that makes sense;
I'm trying to do a basic select statement for a list of companyIDs. The arguments in questions are options regarding invoices. We have multiple invoice types and they can either be set to be sent by E-mail or be printed. They can be mixed as in some e-mail, some printed, some have nothing selected. There's a total of 9 unique invoice types that i need to check for each company ID.
I'm trying to select distinct company IDs(cmp_id) where the print AND e-mail options are all N or NULL for every single invoicetype. Both options have to be off for both print and e-mail for all invoice types ( In the table i'm selecting from, there's 9 records for the same companyID for each invoicetype)
Some examples ( I'm only using 3 invoice types for the example):
Cmp_id invoiceType print e-mail
company1 credit Y N
company1 supplemental Y N
company1 misc Y Y
company2 supplemental N N
company2 misc N N
The results should be a single column for cmp_id; In the example it would only be company2.
Just perfrom a coditional COUNT to check how many 'Y' you have.
Im assuming print and e-mail only have 3 states, Y, N or NULL
SELECT Cmp_id
FROM YourTable
GROUP BY Cmp_id
HAVING COUNT(CASE WHEN print = 'Y' or e-mail = 'Y' THEN 1 END) = 0
So if count is 0 mean all values are NULL or N
Working DEMO
SELECT DISTINCT Cmp_ID
FROM dbo.table
WHERE
COALESCE([Print], 'N') = 'N'
AND
COALESCE([E-Mail], 'N') = 'N'
Use coalesce to catch the NULLs and Ns.
Would this work:
SELECT DISTINCT Cmp_ID from dbo.table where (Print = 'N') AND (E-Mail = 'N') OR
(Print IS NULL) AND (E-Mail IS NULL)
SELECT T1.Cmp_id, COUNT(*)
FROM dbo.table T1
WHERE
COALESCE([Print], 'N') = 'N'
AND
COALESCE([E-Mail], 'N') = 'N'
GROUP BY T1.Cmp_id
HAVING COUNT(T1.Cmp_id) = (SELECT COUNT(1) FROM dbo.table WHERE Cmp_id = T1.Comp_Id)
Count where both options are either NULL or N and that count = the count of Cmp_Ids in the table.
Assumption:
each [Cmp_ID] has n rows in the table where n is the number of [invoiceTypes]
Sample Data:
CREATE TABLE #temp ([Cmp_id] VARCHAR(20), [invoiceType] VARCHAR(20), [print] VARCHAR(20), [e-mail] VARCHAR(20), )
INSERT INTO #temp
VALUES
('company1','credit','Y','N'),
('company1','supplemental','Y','N'),
('company1','misc','Y','Y'),
('company2','credit','N','N'),
('company2','supplemental','N','N'),
('company2','misc','N','N')
Query using Common table Expression, GROUP BY and HAVING:
We assign the value 1 for every row that has [Print], and [e-mail] as NULL or 'N'. Then we only retrieve the [Cmp_id] of the company that has all its invoiceType with [Print], and [e-mail] as NULL or 'N'.
;WITH CTE AS ( SELECT [Cmp_id],
[NoneSelected] = CASE WHEN ISNULL([print],'N') = 'N' AND ISNULL([e-mail],'N') ='N' THEN 1 ELSE 0 END
FROM #temp )
SELECT Cmp_id
FROM CTE
GROUP BY Cmp_id
HAVING SUM(NoneSelected) = 3 --<-- change this to 9 for 9 invoice types
Results:
Try using Temp tables in response to the comment "We're on compatibility 80, i've tried using CTEs before but they didn't work :S Thanks forthe input though.":
IF OBJECT_ID('tempdb..#temp2') IS NOT NULL
DROP TABLE #temp2;
SELECT [Cmp_id],
[NoneSelected] = CASE WHEN ISNULL([print],'N') = 'N' AND ISNULL([e-mail],'N') ='N' THEN 1 ELSE 0 END INTO #temp2
FROM #temp
SELECT Cmp_id
FROM #temp2
GROUP BY Cmp_id
HAVING SUM(NoneSelected) = 3 --<-- change this to 9 for 9 invoice types
I am writing a query like this
select case #flag
when 'Y' then (select * from some table which is having multiple column)
when 'N' then (select * from some table which is having multiple column)
end
as Result
,#flag:='Y'
but it is showing Operand should contain 1 column(s).
I Know that case can only return one column but just want to know if any way is available for this.
You need to select a column in the subqueries:
select (case #flag
when 'Y' then (select col from some table which is having multiple column)
----------------------------------^
when 'N' then (select col from some table which is having multiple column)
end) as Result,
#flag:='Y'
I have a two tables. One has manufacturer information and includes the regions where they can sell. The other has their products for sale. We have to limit visibility of the product based on the regions. This is like Netflix have videos in their system that can only be viewed Everywhere (1), only in Canada (2), only in USA (3).
I am trying to make a query that tells me where the product can be viewed based on the settings in the manufacturer table.
For example, in the manufacturer table, there are two fields called expose_new and expose_used each of which will have a value of 1,2 or 3 to limit where their new or used videos can seen.
When the videos are added, they are not assigned an 'expose' value and this is meant to be done on the fly when adding them to our index depending on the current manufacturer's expose_new or expose_used values.
What I am trying to get is the item details and the computed value for where it can be seen based on whether it is new or used and the rule/value assigned to the manufacturer for all their new or used products. I need this single digit on a per-product basis to conditionally display it in a list.
The following does not work, but you will get the idea of what I am trying to do. I have tried this with CASE statements and the following WRONG IF/ELSEIF statement.
Any help to debugger this and point me in the right direction would be appreciated.
SELECT
t2.company_name,
t2.expose_new, // 1,2 or 3
t2.expose_used, // 1,2 or 3
t1.title,
t1.seller,
t1.status, //can be new or used
(SELECT
IF(status ='New',
(select expose_new from manufacturers where id = t1.seller),1
)
ELSEIF(t1.status ='Used',
(select expose_used from manufacturers where id = t1.seller),1
)
END IF
) as 'expose'
FROM `products` t1
join manufacturers t2 on t2.id = t1.seller
where t1.seller = 4238
Here is a CASE version that actually seems to execute but always results in the first value no matter what happens to be true (in this case 1). I am not sure that I can have the addition of another test with the AND in each WHEN statement but it does not give an error, only the wrong result.
SELECT
t2.company_name,
t2.expose_new,
t2.expose_used,
t1.title,
t1.status,
CASE status
when 'New' and t2.expose_new = 1 then 1
when 'New' and t2.expose_new = 2 then 2
when 'New' and t2.expose_new = 3 then 3
when 'Used' and t2.expose_used = 1 then 1
when 'Used' and t2.expose_used = 2 then 2
when 'Used' and t2.expose_used = 3 then 3
END as expose
FROM `products` t1
join manufacturers t2 on t2.id = t1.seller
where t1.seller = 4238
Try this query -
SELECT
t2.company_name,
t2.expose_new,
t2.expose_used,
t1.title,
t1.seller,
t1.status,
CASE status
WHEN 'New' THEN t2.expose_new
WHEN 'Used' THEN t2.expose_used
ELSE NULL
END as 'expose'
FROM
`products` t1
JOIN manufacturers t2
ON
t2.id = t1.seller
WHERE
t1.seller = 4238
Syntax:
CASE value WHEN [compare_value] THEN result
[WHEN [compare_value] THEN result ...]
[ELSE result]
END
Alternative:
CASE WHEN [condition] THEN result
[WHEN [condition]
THEN result ...]
mysql> SELECT CASE WHEN 2>3 THEN 'this is true' ELSE 'this is false' END;
+-------------------------------------------------------------+
| CASE WHEN 2>3 THEN 'this is true' ELSE 'this is false' END |
+-------------------------------------------------------------+
| this is false |
+-------------------------------------------------------------+
I am use:
SELECT act.*,
CASE
WHEN (lises.session_date IS NOT NULL AND ses.session_date IS NULL) THEN lises.location_id
WHEN (lises.session_date IS NULL AND ses.session_date IS NOT NULL) THEN ses.location_id
WHEN (lises.session_date IS NOT NULL AND ses.session_date IS NOT NULL AND lises.session_date>ses.session_date) THEN ses.location_id
WHEN (lises.session_date IS NOT NULL AND ses.session_date IS NOT NULL AND lises.session_date<ses.session_date) THEN lises.location_id
END AS location_id
FROM activity AS act
LEFT JOIN li_sessions AS lises ON lises.activity_id = act.id AND lises.session_date >= now()
LEFT JOIN session AS ses ON ses.activity_id = act.id AND ses.session_date >= now()
WHERE act.id
Another way of doing this is using nested IF statements. Suppose you have companies table and you want to count number of records in it. A sample query would be something like this
SELECT IF(
count(*) > 15,
'good',
IF(
count(*) > 10,
'average',
'poor'
)
) as data_count
FROM companies
Here second IF condition works when the first IF condition fails. So Sample Syntax of the IF statement would be IF ( CONDITION, THEN, ELSE).
Hope it helps someone.