I’m working with a MS Access database.
I have three tables :
Customers (idCustomer, CustomerName) :
1 C1
2 C2
3 C3
4 C4
5 C5
Products (idProduct, ProductName) :
1 P1
2 P2
3 P3
4 P4
Orders (id, idCustomer, idProduct, Quantity) :
1 2 1 10
2 2 2 15
3 4 2 13
4 5 4 19
I’m working on a query to get this result :
Rows = Customers (all customers)
Columns = Products (all products)
Cells = Quantity
Like this :
P1 P2 P3 P4
C1 0 0 0 0
C2 10 15 0 0
C3 0 0 0 0
C4 0 13 0 0
C5 0 0 0 19
Can anyone help on this query task?
The trick is:
First build a regular SELECT query, joining the 3 tables, that returns the columns you want (CustomerName, ProductName, Quantity)
Then run the crosstab query wizard on this base query, it will be self-explanatory.
I need to to get all the records of my tables customers and products, even the one without records in orders.
Then for the base query in 1. you need a Full Outer Join .
select idcustomer,[1]as p1,[2] as p2,[3] as p3,[4] as p4
from (
select idcustomer ,idproduct,quantity from Orders)ps
pivot
(sum(Quantity)
For idproduct in ([1],[2],[3],[4])
)
pv;
I am still not able to figure how to change the idcustomer to customername but this will help u(m sure for that!!).
Related
I am dealing with the following challenge:
I have multiple (sparse) tables that all share a common date field + common "product_id"s. Additionally each table has one additional field which tracks a specific kind of transactional data for the product, such as "units sold", "units purchased", "received_support_requests", etc.
Table 1
DATE
PRODUCT ID
UNITS SOLD
2022-01-01
1
10
2022-01-02
2
40
Table 2
DATE
PRODUCT ID
UNITS PURCHASED
2022-01-01
2
456
2022-01-04
5
34
Table 3
DATE
PRODUCT ID
RECEIVED SUPPORT REQUESTS
2022-01-04
5
2
2022-01-05
2
1
My goal is to somehow join all of these tables so that I get a master table which shows what happened to each product on a specific day as shown below using MySQL:
DATE
PRODUCT ID
UNITS SOLD
UNITS PURCHASED
RECEIVED SUPPORT REQUESTS
2022-01-01
1
10
0
0
2022-01-01
2
0
456
0
2022-01-02
2
40
0
0
2022-01-04
5
0
34
2
2022-01-05
2
0
0
1
The tables are all very long > 50000
and contain a big list of products > 3000
I first though about building a kind of ("date" - "product id") scaffold and then just left join all of the tables to this scaffold table. Unfortunately the combination of each date, with each product gets too big.
How would you accomplish such a join in a more efficient way?
SELECT date,
product_id,
COALESCE(table1.amount, 0) sold,
COALESCE(table2.amount, 0) purchased,
COALESCE(table3.amount, 0) supported
FROM ( SELECT date FROM table1
UNION
SELECT date FROM table2
UNION
SELECT date FROM table3 ) dates
CROSS
JOIN ( SELECT product_id FROM table1
UNION
SELECT product_id FROM table2
UNION
SELECT product_id FROM table3 ) products
NATURAL LEFT JOIN table1
NATURAL LEFT JOIN table2
NATURAL LEFT JOIN table3
HAVING sold + purchased + supported;
I have 'products' table and related 'variations' table, one product can have one or more variations. 'variations' table has 'status' column, its value can be 0 or 1. I want to get the number of products (COUNT()) which have at least one variation of status 1. How to make a query that would do that?
[EDIT]
Ok, I thought that if I simplify the question I will get away with the table structure, but, here we go (only columns relevant to the question and some mock data):
It's actually 3 linked tables:
table 1: 'products'
id
name
1
t-shirt
2
shoes
3
shorts
table 2: variations
id
product_id
1
1
2
1
3
2
4
2
5
3
6
3
7
3
table 3: stock
variation_id
quantity
status [0 or 1]
1
10
1
2
15
1
3
0
0
4
0
0
5
0
0
6
3
1
7
0
0
So, with this data, I want to know how many products there are that have at least 1 of its 'variations' of 'status' 1 - in this example it would be 2 (product 1 and 3 have some variations with status 1, product 2 does not).
You just need SUM all the quantity GROUP BY products.id with criteria is stock.status equal 1.
SELECT id, name, SUM(quantity) AS total_quantity
FROM Products pr
LEFT JOIN Variations va ON pr.id = va.product_id
LEFT JOIN Stock st ON st.variation_id = va.id
WHERE st.status = 1
GROUP BY pr.id
Join two tables and apply where filter on status column
select count(*) as cnt
from
products p
join variations v
on p.product_id = v.product_id
where status = 1
In MySQL, how to select the records with a specific field doesn't cover all required values?
for example, in the following records, some students finished continuous numbered assignments, like s1 finished from 1 to 5, s4 finished from 1 to 7, but s1 and s4 had different MAX NUMBER of assignments. While some students finished NON-CONTINUOUS numbered assignments, e.g. s2 and s3. how to select the students who have finished CONTINUOUS NUMBERED assignments, regardless the max number?
[[More condition, sorry!]] I need one more column and condition to meet my real work, for example, "failed" column, where 1 means failed, 0 means passed.
Together with the original condition, I also want to exclude those students who have failed one or more assignments, that is, failed must be 0.
In the following records with failed column added, I only want to select student 1, because student 4 has failed assignment (although his assignments number are also continuous)
id student_id assignment_done failed
1 s1 1 0
2 s1 2 0
3 s1 3 0
4 s1 4 0
5 s1 5 0
6 s2 2 0
7 s2 4 0
8 s3 1 0
9 s3 5 0
10 s4 1 0
11 s4 2 0
12 s4 3 0
13 s4 4 0
14 s4 5 0
15 s4 6 0
16 s4 7 1
Try this:
SELECT student_id,
COUNT(CASE failed
WHEN '0' THEN 1
ELSE NULL
END) as failedCount
FROM #yourTableName(e.g, students)
GROUP BY student_id
HAVING COUNT(assignment_done) = MAX(assignment_done)
AND
MAX(assignment_done)=failedCount;
Select student_id from STUDENT group by student_id having count( assignment_done) = max(assignment_done);
+------------+
| student_id |
+------------+
| s1 |
| s4 |
+------------+
2 rows in set (0.00 sec)
In a simple way you can use below sql query
SELECT distinct student_id FROM Students A
WHERE A.student_id in (
SELECT S.student_id
FROM Students S
GROUP BY S.student_id
HAVING COUNT(*) =5
)
Two tables
MEDIA_APPROVALS
[media_id] [firm_id] [approval_status]
FIRM_LIST
[firm_id] [firm_code]
End goal is to show what media is NOT approved by what firm.
By default, all media listed in the MEDIA_APPROVALS table is NOT approved by the firms listed in the FIRM_LIST table. So in order for media to be approved, the row must contain a firm_id with approval_status=1.
If a media piece is in the MEDIA_APPROVALS table & the row contains a firm_id and approval_status=0, that's easy - it's NOT approved.
Where it gets tricky to me is: if there is a MISSING ROW in the MEDIA_APPROVALS table for a media_id/firm_id connection, then that media_id is NOT approved for that firm.
Ultimately I want to arrive at this:
MEDIA_APPROVALS
100 1 1
100 2 1
101 1 0
101 2 0
101 3 1
102 1 1
FIRM_LIST
1 AA
2 BB
3 CC
QUERY OUTPUT
100 CC 0
101 AA 0
101 BB 0
102 BB 0
102 CC 0
I am a PHP/web programmer and NOT a db admin. The help is HUGELY appreciated!
So you need every possible combination of Media and Firm? Ooh, that's a CROSS JOIN. We don't get to do those very often:
WITH MediaFirms As (
SELECT m_id.media_id, f_id.firm_id
FROM (SELECT DISTINCT media_id FROM MEDIA_APPROVALS) m_id
CROSS JOIN (SELECT DISTINCT firm_ID FROM FIRM_LIST) f_id
)
SELECT mf.media_id, mf.firm_id, coalesce(ma.approval_status, 0) "approval_status"
FROM MediaFirms mf
LEFT JOIN MEDIA_APPROVALS ma ON ma.media_id = mf.media_id AND ma.firm_id = mf.firm_id
WHERE coalesce(ma.approval_status,0) <> 1;
I'm trying to make a crosstab query (with access tables), But I got lost writing the inner joins statements.
My end result suppose to be the "QueryResult".
Table1 holds the fund information,
Table2 are the type of data the funds have
Table3 is a conversion from the codes of the data to the type data in table2, and Table4 holds the data.
Table1
FundID FundName
1 Fund1
2 Fund2
3 Fund3
4 Fund4
5 Fund5
6 Fund6
7 Fund7
Table2
TypeID TypeName
1 Balance
2 Yield
3 Fees
4 Deposits
5 Withdraws
Table3
CodeID TypeID
KT111 1
KT112 2
KT113 3
KT115 3
KT116 4
KT117 4
KT118 5
KT119 5
Table 4
CodeID FundID DataVal
KT111 1 1000
KT116 2 40
KT118 3 30
KT119 3 30
KT118 2 10
KT119 2 50
KT111 2 3000
KT111 3 2000
KT112 1 1.5
KT112 2 1.0
KT112 3 0.5
P.S: Table4 holds much rows then shown here with codes which I do not need.
QueryResult
FundID Balance Yield Fees Deposits Withdraws
1 1,000 1.5 555 40 60
2 3,000 1.0 155 20 60
3 2,000 0.5 255 70 60
What is the right statement to get the query result? (I got lost on the inner joins...)
Is there also a way to sum some of the data, and show the value (without summing) of other data from table4?
Thanks!
while I am not exactly sure of all of the requirements you have, this might get you started:
TRANSFORM Sum(d.dataval) as DataValue
SELECT d.fundid
FROM
((Data d
INNER JOIN fund f ON d.fundid = f.fundid)
INNER JOIN code c ON d.codeid = c.codeid)
INNER JOIN type t on c.typeid = t.typeid
GROUP BY d.fundid
PIVOT T.Typename
Results:
fundid Balance Deposits Withdraws Yield
1 1000 1.5
2 3000 40 60 1
3 2000 60 0.5