Conversion error using CASE on a varchar column - tsql

I'm trying to grab information to send to Google Charts for a graph I'm looking at the column Active which can be true/false but is set to varchar in my database.
Using this query:
SELECT
SUM(CASE WHEN CONVERT(int, Active) Active = 1 THEN 1 ELSE 0 END) AS Active,
SUM(CASE WHEN CONVERT(int, Active) Active = 0 THEN 1 ELSE 0 END) AS Inactive
FROM
Events
throws this error:
Conversion failed when converting the varchar value 'True' to data type int.`

Ints are not booleans.... they are called bit in SQL Server. try;
SELECT
SUM(CASE WHEN CONVERT(bit, Active) = 1 THEN 1 ELSE 0 END) AS Active,
SUM(CASE WHEN CONVERT(bit, Active) = 0 THEN 1 ELSE 0 END) AS Inactive
FROM Events
Or just test for your String
SELECT
SUM(CASE WHEN Active = 'True' THEN 1 ELSE 0 END) AS Active,
SUM(CASE WHEN Active = 'False' THEN 1 ELSE 0 END) AS Inactive
FROM Events
P.S. Storing Boolean values as String columns is silly... Consider changing the column to be a bit column so you don't even need to convert it

Related

Postgres: Extracting the IDs and names of people who are cheating the system

I have a table A with the following transaction data:
ID Name Type
1 Albert Rewards
2 Albert Visit
3 Ruddy Rewards
4 Ruddy Visit
5 Ruddy Purchase
6 Mario Rewards
7 Mario Visit
...
I want a table that only select the rows with names of people who used the "Rewards" and "Visit" type but didn't make a purchase, something like this:
ID Name Type
1 Albert Rewards
2 Albert Visit
6 Mario Rewards
7 Mario Visit
...
Any ideas?
The below query will count for every Visit/Rewards/Purchase how often they happened for a given name - and if the respective results are 1/1/0 then all records from the table with that name will be returned.
If fine-tuning is required (such as cases where the count of any of those > 1 etc.) that can be done by fiddling with the numbers in the 'having' clause. The same is true for adding additional categories to check against.
select *
from mytable a
where exists (select b.name,
sum(case when b.type='Rewards' then 1 else 0 end),
sum(case when b.type='Visit' then 1 else 0 end),
sum(case when b.type='Purchase' then 1 else 0 end)
from mytable b
where b.name=a.name
group by b.name
having sum(case when b.type='Rewards' then 1 else 0 end) = 1
and
sum(case when b.type='Visit' then 1 else 0 end) = 1
and
sum(case when b.type='Purchase' then 1 else 0 end) = 0);
For completion sake: SQLFiddle with 2 queries First query also works, but a little differently

TSQL Reversing query to display cols as rows

The following query will gives me
Active Inactive
3 1
SELECT
SUM(CASE WHEN Active = 'True' THEN 1 ELSE 0 END) AS Active,
SUM(CASE WHEN Active = 'False' THEN 1 ELSE 0 END) AS Inactive
FROM Events
I would like to get it like:
Status Count
Active 3
Inactive 1
How can I inverse this?
There is no need for pivoting your resultset, you could use simple GROUP BY:
SELECT CASE Active WHEN 'True' THEN 'Active'
WHEN 'False' THEN 'Inactive'
END AS Status
,COUNT(*) AS Count
FROM Events
WHERE Active IN ('True', 'False')
GROUP BY CASE Active WHEN 'True' THEN 'Active'
WHEN 'False' THEN 'Inactive'
END;

order by with operation on select case query

I want to rank a table by multi-columns and sum of each point that is decided by value.
For example, I can get some columns and each points by below query.
select
(case when seller=true then 50 else 0 end) as sel,
(case when buyer=true then 40 else 0 end) as buy
from company;
but I can't order by this values by like this query
select
(case when seller=true then 50 else 0 end) as sel,
(case when buyer=true then 40 else 0 end) as buy
from company
order by (sel + by);
or this
select
(case when seller=true then 50 else 0 end) as sel,
(case when buyer=true then 40 else 0 end) as buy,
(sell, buy) as sm
from company
order by sm;
How can I do that?
Oh, sorry, I found the answer.
select * from
(select
(case when seller=true then 50 else 0 end) as sel,
(case when buyer=true then 40 else 0 end) as buy
from company) as tmp
order by (tmp.sel + tmp.buy);

Using field alias in MSQuery does not work with DB2

This query works in data studio, but fails to show alias in MS Query!
I have tried different types such as "",'',[] and even https://support.microsoft.com/en-us/kb/298955
SELECT 'TRANIN'AS NAME, SUM(CASE WHEN ALT3.TRANINDT BETWEEN 20150603 AND 20150601 THEN 1 else 0 END) AS CurrentMonth, SUM(CASE WHEN ALT3.TRANINDT BETWEEN 20150501 AND 20150531 THEN 1 else 0 END) AS LastMonth
FROM ALT3
MS broke MS query a long time ago...
I've tried to get it to work right, but nothing worked. I've pretty much given up.
Normally I just rename the column once the data is back in Excel.
But if you really want the name returned from MS query, this works:
WITH tbl AS (SELECT 'TRANIN'AS NAME
, SUM(CASE WHEN ALT3.TRANINDT BETWEEN 20150603 AND 20150601
THEN 1 else 0 END) AS CurrentMonth
, SUM(CASE WHEN ALT3.TRANINDT BETWEEN 20150501 AND 20150531
THEN 1 else 0 END) AS LastMonth
FROM ALT3)
SELECT * FROM TBL

Count valid values per user

I have a table with a list of values. -1 is a blank value:
ID FieldType1A FieldType1B FieldType2A FieldType2B Person
1 15 14 10 -1 1
2 16 -1 12 10 1
3 17 -1 5 6 1
4 6 -1 7 -1 2
...
So the result should be:
Person FieldType1 FieldType2
1 4 5
2 1 1
there is a users table with a list of user IDs, would there be a way of iterating over that list of values to generate the person list in the result set (0 for the field types being perfectly valid as it is merely counts)? I think the answer to T-SQL Column Values Count is a step in the direction I'm attempting to go, but unsure how to combine columns that are the same (the A/Bs allow for a list of answers). That and I'm interested in combining all valid values as not attempting to count the number of each valid response.
You can use a CASE expression to change all non-negative-one values to 1, and -1 values to 0, and then sum them up.
SELECT Person,
SUM(CASE WHEN FieldType1A <> -1 THEN 1 ELSE 0 END) +
SUM(CASE WHEN FieldType1B <> -1 THEN 1 ELSE 0 END) AS FieldType1,
SUM(CASE WHEN FieldType2A <> -1 THEN 1 ELSE 0 END) +
SUM(CASE WHEN FieldType2B <> -1 THEN 1 ELSE 0 END) AS FieldType2
FROM YourTable
GROUP BY Person
SELECT Person,
count(nullif(FieldType1A, -1)) + count(nullif(FieldType1B, -1)) as FieldType1,
count(nullif(FieldType2A, -1)) + count(nullif(FieldType2B, -1)) as FieldType2
FROM yourtable
GROUP BY person