TSQL Reversing query to display cols as rows - tsql

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;

Related

Postgresql how to group the values in on column of a table and transpose the unique values of another column in the same table, and sum up the rows

I am new to SQL in general, hence this problem is a little tricky to me. I have a table like the example below:
Input Values:
And, I wish to get the following output:
Output Result:
Honestly, I have no idea how to begin to solve this problem. I would appreciate a hint and/or an example solution from anyone. Thank you in advance.
You can perform conditional aggregation and then use a ROLLUP.
For example:
select
velocity,
sum(case when volume = 'VERY HIGH' then sales else 0 end) as very_high,
sum(case when volume = 'HIGH' then sales else 0 end) as high,
sum(case when volume = 'MEDIUM-HIGH' then sales else 0 end) as medium_high,
sum(case when volume = 'LOW' then sales else 0 end) as low,
sum(case when volume = 'VERY LOW' then sales else 0 end) as very_low,
sum(sales) as total
from t
group by rollup (velocity)
order by velocity

Postgresql query first and last in every range

I have table
id
machineid
reset
1
1
false
2
1
false
3
1
false
4
1
true
5
1
false
15
1
true
17
1
false
20
2
false
21
2
false
25
2
false
30
2
false
I cant figure out how to find first and last id for every machine. Reset create new range for next rows. Result should look like:
machineid
startid
endid
1
1
3
1
4
5
1
15
17
2
20
30
you can start from grouping your records into groups or ranges. As the order of your records matter, it indicates you can make use of window functions. You have to determine how you are going to uniquely name these groups. I suggest you use the number of resets above the record. This result to this statement:
SELECT *
, SUM(case when reset then 1 else 0 end) over (partition by machineid order by id) as reset_group
FROM
test;
After that finding the start and end ids is a simple GROUP BY statement:
SELECT
machineid, MIN(id) as startid, MAX(id) as endid
FROM (
SELECT machineid, id
, SUM(case when reset then 1 else 0 end) over (partition by machineid order by id) as reset_group
FROM
test
) as grouped
GROUP BY
machineid, reset_group
ORDER BY
machineid, startid;
Please try it out: db<>fiddle

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

Conversion error using CASE on a varchar column

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

crystal reports-count

Hai Friends
this is my query
SELECT
COUNT(CASE ISNULL(GAM_STATUS, ' ')
WHEN '1' THEN '1'
END) + COUNT(CASE ISNULL(GAM_STATUS, ' ')
WHEN '2' THEN '2'
END) + COUNT(CASE ISNULL(GAM_STATUS, ' ')
WHEN '3' THEN '3'
END) ACTIVE_REC,
COUNT(CASE ISNULL(GAM_STATUS, ' ')
WHEN '5' THEN '5'
END) DELETED,
COUNT(CASE ISNULL(GAM_STATUS, ' ')
WHEN '4' THEN '4'
END) SOLD
FROM GLAS_ASSET_MASTER_T
WHERE GAM_COMP_CODE = '1' and gam_dept_code between '01' and '03'
output is
active_rec deleted sold
50 20 25
same should come in the crystal reports how can i count the records
in the crystal reports according to the conditions.
A common method is something like the following :
Formula name : #Active_Rec
Formula text : If {GLAS_ASSET_MASTER_T.GAM_STATUS} IN [1,2,3] Then 1 Else 0
Formula name : #Deleted_Rec
Formula text : If {GLAS_ASSET_MASTER_T.GAM_STATUS} = 5 Then 1 Else 0
Formula name : #SoldRec
Formula text : If {GLAS_ASSET_MASTER_T.GAM_STATUS} = 4 Then 1 Else 0
Place those formula in the report's Details section, and add Summary Fields for them to your Report Footer.
And of course your record selection formula would be
{GLAS_ASSET_MASTER_T.GAM_COMP_CODE} = '1' and {GLAS_ASSET_MASTER_T.gam_dept_code} between '01' and '03'