Sql query - Order by number of true values in the columns - sql

I have a table like this
I need to get the validity order by the number of true values in the last 4 columns.
For e.g. the output of the below query should be
1110 // 4 true values
1001 // 2 true values
1000 // 1 true value

You can use subquery;
SELECT subquery.VALIDITY,
concat(CAST ((subquery.TAXI + subquery.CAR + subquery.TRUCK + subquery.BIKE) AS TEXT) , ' True values') as COUNTTRUEVALUES
FROM (select VALIDITY,
CASE WHEN TAXI THEN 1 ELSE 0 END AS TAXI,
CASE WHEN CAR THEN 1 ELSE 0 END AS CAR,
CASE WHEN TRUCK THEN 1 ELSE 0 END AS TRUCK,
CASE WHEN BIKE THEN 1 ELSE 0 END AS BIKE
FROM YourTableName) as subquery
ORDER BY 2 DESC
output
VALIDITY COUNTTRUEVALUES
1110 4 True values
1001 2 True values
1000 1 True values

Convert the boolean values to integers and order descending by their total:
SELECT *
FROM tablename
ORDER BY taxi::int + car::int + truck::int + bike::int DESC;
See the demo.

What about something like this?
SELECT
id,
validity,
taxi1 + car1 + truck1 + bike1
FROM
(
SELECT
id,
validity
CASE WHEN taxi = 'TRUE' THEN 1 ELSE 0 END taxi1,
CASE WHEN car = 'TRUE' THEN 1 ELSE 0 END car1,
CASE WHEN truck = 'TRUE' THEN 1 ELSE 0 END truck1,
CASE WHEN bike = 'TRUE' THEN 1 ELSE 0 END bike1
FROM table
)

Related

Count entries per row in teradata

I have a table with a row per customer and columns that are attributes about that customer. I want to know for each customer how many attributes are populated...i.e. not null values.
As an example I have this:
And I want my output to be this:
What would be the sql for this?
You can use a case expression:
select customer,
(case when col1 is not null then 1 else 0 end +
case when col2 is not null then 1 else 0 end +
case when col3 is not null then 1 else 0 end +
case when col4 is not null then 1 else 0 end +
case when col5 is not null then 1 else 0 end
) as num_entries
from t;

Two select statement with case

I have two queries and I have a value if value is 1 then first query will execute if value is 2 then second. How can i achieve this, my query is
Query one if value is 1
SELECT count (CASE WHEN col1 = 9 THEN 1 ELSE 0 END )AS "matches" ,
CAST( CASE WHEN col1 = 9 THEN 1 ELSE 0 END AS VARCHAR(10)) + ' / 1' AS "match by"
FrOM table a
where ( SELECT CASE WHEN col1 = 9 THEN 1 ELSE 0 END AS "matches" ) >= 1
group by ( CASE WHEN col1 = 9 THEN 1 ELSE 0 END )
)
Query 2 if value 2
SELECT count (CASE WHEN col1 = 9 THEN 1 ELSE 0 END +
CASE WHEN col2 = 10 THEN 1 ELSE 0 END
)AS "matches" ,
CAST( CASE WHEN col1 = 9 THEN 1 ELSE 0 END
+ CASE WHEN col2 = 10 THEN 1 ELSE 0 END AS VARCHAR(10)) + '/ 2' AS "match by"
FrOM table a
where ( SELECT CASE WHEN col1 = 9 THEN 1 ELSE 0 END +
CASE WHEN col2 = 10 THEN 1 ELSE 0 END AS "NUM_OF_MATCHES" ) >= 1
group by ( CASE WHEN col1 = 9 THEN 1 ELSE 0 END+
CASE WHEN col2 = 10 THEN 1 ELSE 0 END )
I have try it using case but it is not working
I want if value = 1 then first query will run and if value = 2 then second
although both queries doing same work but if value is 1 then col1 logic will take only col1 and if value is 2 then it will take col1 and col2 if value is 3 then it will take col1 col2 and col3 till 6 col
You can make use of a simple if else if and execute both the queries.
IF(#value=1)
BEGIN
SELECT count (CASE WHEN col1 = 9 THEN 1 ELSE 0 END )AS "matches" ,
CAST( CASE WHEN col1 = 9 THEN 1 ELSE 0 END AS VARCHAR(10)) + ' / 1' AS "match by"
FrOM table a
where ( SELECT CASE WHEN col1 = 9 THEN 1 ELSE 0 END AS "matches" ) >= 1
group by ( CASE WHEN col1 = 9 THEN 1 ELSE 0 END )
)
END
ELSE IF(#value=2)
BEGIN
SELECT count (CASE WHEN col1 = 9 THEN 1 ELSE 0 END +
CASE WHEN col2 = 10 THEN 1 ELSE 0 END
)AS "matches" ,
CAST( CASE WHEN col1 = 9 THEN 1 ELSE 0 END
+ CASE WHEN col2 = 10 THEN 1 ELSE 0 END AS VARCHAR(10)) + '/ 2' AS "match by"
FrOM table a
where ( SELECT CASE WHEN col1 = 9 THEN 1 ELSE 0 END +
CASE WHEN col2 = 10 THEN 1 ELSE 0 END AS "NUM_OF_MATCHES" ) >= 1
group by ( CASE WHEN col1 = 9 THEN 1 ELSE 0 END+
CASE WHEN col2 = 10 THEN 1 ELSE 0 END )
END
still are you using CASE Statement, why dont you try to use IIF Statement, IIF Statement is more efficient and fast compare to CASE Statement.
e.g.
select IIF(1=1, (your desired column1),(your desired column2)) as matches
you can also use nested IIF Statement in single query like CASE Statement..
select IIF(1=1, (IIF(2=2, (your desired column1),(your desired column2))),(your desired column3)) as matches.

Case statement result to another case

I need to combine below logic and put it in a sql statement.
Logic:
CASE WHEN (ABC = 2)
THEN 0
ELSE 1
END XYZ
IF XYZ > 1
THEN
FINAL_COLUMN = 10
ELSE
FINAL_COLUMN = 20
SQL :
select (CASE WHEN(CASE ABC=2 then 0 Else 1 END AS) XYZ >123
Then 10 ELSE 100 ) END AS FINAL_COLUMN
from Table 1;
The syntax for the case statement is
Case
When Condition1 Then Value
When Condition2 Then Value2
Else Value
End
So your statement should look like
Select CASE WHEN ABC = 2 Then 0 Else 1 End AS FINAL_COLUMN from Table 1;

Order SQL query by the sum of specefic columns

Here is an extract from the fairly large table (SQL Server 2005) I'm querying against:
id (primary key) | account | phone | employee | address
------------------------------------------------------------------
1 | 123 | Y | Y | N
2 | 456 | N | N | N
3 | 789 | Y | Y | Y
I need to only return the rows that have at least one Y in phone, employee, or address (there are about 10 others not shown here). Then I need to order those results by the number of Y's they have in any of the three.
I've tried getting the "tagTotal" like this:
SELECT
SUM(
CASE WHEN [phone] = 'Y' THEN 1 ELSE 0 END
+ CASE WHEN [employee] = 'Y' THEN 1 ELSE 0 END
+ CASE WHEN [address] = 'Y' THEN 1 ELSE 0 END
)
FROM table
GROUP BY id
this returns:
tagTotal
---------------
2
0
3
I'm at a loss on how to combine this with my existing giant query and order by it without adding each column to the group by at the end.
Since the sum of values you're after is on the same row, you don't need to aggregrate the results, thereby eliminating the need for the group by..
SELECT
CASE WHEN [phone] = 'Y' THEN 1 ELSE 0 END +
CASE WHEN [employee] = 'Y' THEN 1 ELSE 0 END +
CASE WHEN [address] = 'Y' THEN 1 ELSE 0 END as Total
FROM table
You can just do the addition as a column and then order the results. The aggregation seems unnecessary, at least with the sample data in the question. There is only one row per id.
SELECT t.*
FROM (SELECT t.*,
((CASE WHEN [phone] = 'Y' THEN 1 ELSE 0 END) +
(CASE WHEN [employee] = 'Y' THEN 1 ELSE 0 END) +
(CASE WHEN [address] = 'Y' THEN 1 ELSE 0 END)
) as NumYs
FROM table t
) t
WHERE NumYs > 0
ORDER BY NumYs DESC;
Try selecting the ID and ordering by the sum?
SELECT id,
SUM(
CASE WHEN [phone] = 'Y' THEN 1 ELSE 0 END
+ CASE WHEN [employee] = 'Y' THEN 1 ELSE 0 END
+ CASE WHEN [address] = 'Y' THEN 1 ELSE 0 END
) as numsum
FROM table
ORDER BY numsum
This should work:
select *
from
(
SELECT
id,
SUM(
CASE WHEN [phone] = 'Y' THEN 1 ELSE 0 END
+ CASE WHEN [employee] = 'Y' THEN 1 ELSE 0 END
+ CASE WHEN [address] = 'Y' THEN 1 ELSE 0 END
) tagTotal
FROM table
GROUP BY id
) x
where x.tagTotal <> 0
order by x.tagTotal desc
The inner query is basically yours, with the addition of the Id (which I assume you need) and giving the sum a name. This is then used as the input to the outer query, excluding those with a zero total and sorting with highest sum first.
(Incidentally, this is not a large query. The largest single select statement I have written covered over 250 lines, took 20 minutes to run, and did the daily P&L of a commodity trading company. That was large...)

select true if more then 0 in t-sql

I would like to perform query in which as a result I have column with false if the value in former column is 0 and true if is greater then 0:
as example:
id count
1 1
2 3
3 0
4 5
5 2
result:
id count
1 true
2 true
3 false
4 true
5 true
select
id,
case
when count > 0 then 'true'
else 'false'
end as count
from myTable
select id
, case when count > 0 then cast(1 as bit) else cast(0 as bit) end as count
from myTable