I'd appreciate if somebody could help me with this.
In postgres I have table that looks like this
id | main_table_id | tax_id | value | tax_value
------ | ------------ | ------ | ------ | ------
1 | 1 | 1 | 10.00 | 1.00
2 | 1 | 2 | 15.00 | 2.00
3 | 1 | 1 | 17.00 | 3.00
Somehow, I need to sum columns 'value' and 'tax_value' over tax_id and get result like this
| main_table_id | sum_value_1 | sum_value_2 | sum_tax_value_1 | sum_value_2
| ------------ | ------ ------| ------------ | -----------------| -------
| 1 | 27.00 | 15.00 | 4.00 | 2.00
sum_value_1 is sum(value) for tax_id= 1,
sum_value_2 is sum(value) for tax_id= 2,
sum_tax_value_1 is sum(tax_value) for tax_id= 1,
sum_tax_value_2 is sum(tax_value) for tax_id= 2..
In table 'taxes' I have 10 different taxes, and tax_id is its FK.
Is it posible?
One method is conditional aggregation:
select mt.main_table_id,
sum(case when mt.tax_id = 1 then mt.value else 0 end) as sum_value_1,
sum(case when mt.tax_id = 1 then mt.tax_value else 0 end) as sum_tax_value_1,
sum(case when mt.tax_id = 2 then mt.value else 0 end) as sum_value_2,
sum(case when mt.tax_id = 2 then mt.tax_value else 0 end) as sum_tax_value_2
from maintable mt
group by mt.main_table_id;
You can easily generalize this by adding more sum( . . . ) expressions.
SELECT SUM(VALUE), SUM(TAX_VALUE) FROM TABLE_NAME GROUP BY TAX_ID;
Related
I have grouped sales from a sales view with sales below using
Select id, name, Count(*) as [Sales], product, amount
from vwSales
Group by
id,name, product, amount
ID | Name | Sales | Product | Amount
1 | Bob | 4 | Fridge | 40
1 | Bob | 12 | Washer | 120
2 | Anne | 5 | Fridge | 50
2 | Anne | 4 | Washer | 40
Is it possible to group these in to one row without using a join? So table looks something like
ID | Name | Fridge Sales | fridge Amt | Washer sales | washer amt
1 | Bob | 4 | 40 | 12 | 120
2 | Anne | 5 | 50 | 4 | 40
You can do conditional aggregation :
select id, name,
sum(case when Product = 'Fridge' then 1 else 0 end) as [Fridge Sales],
sum(case when Product = 'Fridge' then Amount else 0 end) as [fridge Amt],
sum(case when Product = 'Washer' then 1 else 0 end) as [Washer Sales],
sum(case when Product = 'Washer' then Amount else 0 end) as [Washer Amt]
from vwSales
Group by id, name;
Given tables CollegeMajors
| Id | Major |
|----|-------------|
| 1 | Accounting |
| 2 | Math |
| 3 | Engineering |
and EnrolledStudents
| Id | CollegeMajorId | Name | HasGraduated |
|----|----------------|-----------------|--------------|
| 1 | 1 | Grace Smith | 1 |
| 2 | 1 | Tony Fabio | 0 |
| 3 | 1 | Michael Ross | 1 |
| 4 | 3 | Fletcher Thomas | 1 |
| 5 | 2 | Dwayne Johnson | 0 |
I want to do a query like
Select
CollegeMajors.Major,
Count(select number of students who have graduated) AS TotalGraduated,
Count(select number of students who have not graduated) AS TotalNotGraduated
From
CollegeMajors
Inner Join
EnrolledStudents On EnrolledStudents.CollegeMajorId = CollegeMajors.Id
and I'm expecting these kind of results
| Major | TotalGraduated | TotalNotGraduated |
|-------------|----------------|-------------------|
| Accounting | 2 | 1 |
| Math | 0 | 1 |
| Engineering | 1 | 0 |
So the question is, what kind of query goes inside the COUNT to achieve the above?
Select CollegeMajors.Major
, COUNT(CASE WHEN EnrolledStudents.HasGraduated= 0 then 1 ELSE NULL END) as "TotalNotGraduated",
COUNT(CASE WHEN EnrolledStudents.HasGraduated = 1 then 1 ELSE NULL END) as "TotalGraduated"
From CollegeMajors
InnerJoin EnrolledStudents On EnrolledStudents.CollegeMajorId = CollegeMajors.Id
GROUP BY CollegeMajors.Major
You can use the CASE statement inside your COUNT to achieve the desired result.Please try the below updated query.
Select CollegeMajors.Major
, COUNT(CASE WHEN EnrolledStudents.HasGraduated= 0 then 1 ELSE NULL END) as "TotalNotGraduated",
COUNT(CASE WHEN EnrolledStudents.HasGraduated = 1 then 1 ELSE NULL END) as "TotalGraduated"
From CollegeMajors
InnerJoin EnrolledStudents On EnrolledStudents.CollegeMajorId = CollegeMajors.Id
GROUP BY CollegeMajors.Major
You can try this for graduated count:
Select Count(*) From EnrolledStudents group by CollegeMajorId having HasGraduated = 1
And change 1 to zero for not graduated ones:
Select Count(*) From EnrolledStudents group by CollegeMajorId having HasGraduated = 0
I have a table with this structure:
+--------+-----------+------------+------+
| userid | date | item | rank |
+--------+-----------+------------+------+
| 34444 | 01-Jul-15 | pen | 3 |
| 34444 | 04-Jul-15 | TV | 2 |
| 34444 | 09-Jul-15 | controller | 1 |
| 531 | 03-Jul-15 | keyboard | 3 |
| 531 | 06-Jul-15 | pen | 2 |
| 531 | 10-Jul-15 | bowl | 1 |
+--------+-----------+------------+------+
Each item has already been ranked based on their dates with a limit of 3 items per user. I have their last 3 items and the dates associated with them. The items can be anything.
I want to produce a view in a way that pivots the date and item combination. For example, the desired view for this table is:
+--------+------------+-----------+-------+-----------+----------+-----------+
| userid | item1 | date1 | item2 | date2 | item3 | date3 |
+--------+------------+-----------+-------+-----------+----------+-----------+
| 34444 | controller | 09-Jul-15 | TV | 04-Jul-15 | pen | 01-Jul-15 |
| 531 | bowl | 10-Jul-15 | pen | 06-Jul-15 | keyboard | 03-Jul-15 |
+--------+------------+-----------+-------+-----------+----------+-----------+
Is this possible?
Thanks
You just need to do a pivot. In more recent versions, you can use the actual pivot keyword. Or in any version, you can just do
SELECT userid,
max( case when rank = 1 then item else null end) item1,
max( case when rank = 1 then date else null end) date1,
max( case when rank = 2 then item else null end) item2,
max( case when rank = 2 then date else null end) date2,
max( case when rank = 3 then item else null end) item3,
max( case when rank = 3 then date else null end) date3
FROM your_table
GROUP BY userid
i need to do one select with different where clauses (with different product code). The result which i need is below.
I have table like:
ApID | Date | Code | Qty | Price | Sum
222 | 2014-10-11 | 555 | 1 | 2,22 | 2,22
222 | 2014-10-11 | 555 | 1 | 2,22 | 2,22
222 | 2014-10-11 | 333 | 1 | 3,33 | 3,33
222 | 2014-10-12 | 555 | 1 | 2,22 | 2,22
My query:
SELECT
CAST(Date AS DATE) as 'Data',
SUM(Qty*Price) AS 'Sum',
SUM(Qty) AS 'Qty'
FROM Table
WHERE ApID = 222
AND Data BETWEEN '2014-10-11' AND '2014-10-13'
AND Code LIKE '555'
GROUP BY CAST(KvitoGalva.Data AS DATE)
I get result like this:
Data | Sum | Qty
2014-10-11 | 4.44 | 2
2014-10-12 | 2.22 | 1
I need to display result in one table:
Data | Sum 555 | Qty 555 | Sum 333 | Qty 333 |
2014-10-11 | 4.44 | 2 | 3.33 | 1 |
2014-10-12 | 2.22 | 1 | 0 | 0 |
Tried:
SELECT((Select1),(Select2))
----------------------------
SELECT 1
union
select 2
You can do this using conditional aggregation:
SELECT CAST(Date AS DATE) as Data,
SUM(case when code = '555' then Qty*Price else 0 end) AS Sum555,
SUM(case when code = '555' then Qty else 0 end) AS Qty555,
SUM(case when code = '333' then Qty*Price else 0 end) AS Sum333,
SUM(case when code = '333' then Qty else 0 end) AS Qty333
FROM Table t
WHERE ApID = 222 AND
Data BETWEEN '2014-10-11' AND '2014-10-13' AND
Code IN ('555', '333')
GROUP BY CAST(KvitoGalva.Data AS DATE);
Note: only use single quotes for string and date constants. You do not need quotes for column aliases and if you did, then your database would have a better character for escaping the names.
I apologize if this is a duplicate question but I could not find my answer.
I am trying to take data that is horizontal, and get a count of how many times a specific number appears.
Example table
+-------+-------+-------+-------+
| Empid | KPI_A | KPI_B | KPI_C |
+-------+-------+-------+-------+
| 232 | 1 | 3 | 3 |
| 112 | 2 | 3 | 2 |
| 143 | 3 | 1 | 1 |
+-------+-------+-------+-------+
I need to see the following:
+-------+--------------+--------------+--------------+
| EmpID | (1's Scored) | (2's Scored) | (3's Scored) |
+-------+--------------+--------------+--------------+
| 232 | 1 | 0 | 2 |
| 112 | 0 | 2 | 1 |
| 143 | 2 | 0 | 1 |
+-------+--------------+--------------+--------------+
I hope that makes sense. Any help would be appreciated.
Since you are counting data across multiple columns, it might be easier to unpivot your KPI columns first, then count the scores.
You could use either the UNPIVOT function or CROSS APPLY to convert your KPI columns into multiple rows. The syntax would be similar to:
select EmpId, KPI, Val
from yourtable
cross apply
(
select 'A', KPI_A union all
select 'B', KPI_B union all
select 'C', KPI_C
) c (KPI, Val)
See SQL Fiddle with Demo. This gets your multiple columns into multiple rows, which is then easier to work with:
| EMPID | KPI | VAL |
|-------|-----|-----|
| 232 | A | 1 |
| 232 | B | 3 |
| 232 | C | 3 |
| 112 | A | 2 |
Now you can easily count the number of 1's, 2's, and 3's that you have using an aggregate function with a CASE expression:
select EmpId,
sum(case when val = 1 then 1 else 0 end) Score_1,
sum(case when val = 2 then 1 else 0 end) Score_2,
sum(case when val = 3 then 1 else 0 end) Score_3
from
(
select EmpId, KPI, Val
from yourtable
cross apply
(
select 'A', KPI_A union all
select 'B', KPI_B union all
select 'C', KPI_C
) c (KPI, Val)
) d
group by EmpId;
See SQL Fiddle with Demo. This gives a final result of:
| EMPID | SCORE_1 | SCORE_2 | SCORE_3 |
|-------|---------|---------|---------|
| 112 | 0 | 2 | 1 |
| 143 | 2 | 0 | 1 |
| 232 | 1 | 0 | 2 |