COUNT from two different tables - mysql

This is a funky question, I know this. And maybe it's all because I'm really tired.
Now, don't blame the design - it is flawed, but nothing I can do anything about, ok?
Two tables, linked by a id-field.
First table contains positions in a warehouse (table P)
Second table contains articles stored on each position in the warehouse (table PA)
ALL positions in the warehouse are present in the P-table (> 5000 records)
Each position could contain more than one article
The are positions in the P-table not present in the PA-table
The count from positionarticles PLUS the positions not present in positionarticles.
Is there really no better way than this utter stupidity?:
SELECT SUM(row)
FROM
(
SELECT COUNT(*) row
FROM PA
UNION
SELECT COUNT(*)
FROM P
WHERE ID NOT IN
(
SELECT P_ID
FROM PA
)
) as rowcounter
Sample data
Table P:
ID Name
1 A01
2 A03
3 B01 *
4 B02 *
Table PA:
ID P_ID A_ID
1 1 201 *
2 1 202 *
3 1 203 *
4 2 205 *
And the count returned is 6 => 4 rows from PA + 2 rows (P_IDs not present in PA). Rows counted are star-marked (*).

Try this:
SELECT P.ID, COUNT(PA.ID) noOfArticles
FROM P
LEFT JOIN PA ON P.ID = PA.P_ID
GROUP BY P.ID

Related

MySQL - select product_id from 2 different tables and group results

situation:
table 1 - #__virtuemart_products
virtuemart_product_id | product_special
PRODUCTS_IDS | 0 or 1
table 2 - #__virtuemart_product_badges
virtuemart_product_id | product_badge
PRODUCTS_IDS | for this situation code 3
I have a default SQL
SELECT p.`virtuemart_product_id`
FROM `#__virtuemart_products` as p
WHERE p.`product_special` = 1;
results is product IDs like 2,3,225,...
I need modify this SQL syntax for select IDs from 2 different tables and return one column.
If I modify syntax like that:
SELECT p.`virtuemart_product_id`, badges_table.`virtuemart_product_id`
FROM `#__virtuemart_products` as p, `#__virtuemart_product_badges` as badges_table
WHERE p.`product_special` = 1 OR badges_table.`badge` = 3
Result is:
virtuemart_product_id | virtuemart_product_id
1 | 123
1 | 321
1 | 231
....
why is first column 1,1,1,...? here must be product_id, no product_special code
I need group this results into one column virtuemart_product_id
What I doing wrong?
I think what you are looking for is UNION of the IDs fetched from two different tables.
SELECT p.`virtuemart_product_id`, badges_table.`virtuemart_product_id`
FROM `#__virtuemart_products` as p, `#__virtuemart_product_badges` as
badges_table
WHERE p.`product_special` = 1 OR badges_table.`badge` = 3
What the above query is doing is, it is performing a join between the two tables with the condition that product_special should be 1 or badge should be 3. Hence, each row from one table will be joined with each row of the other table where the condition will satisfy.
To get IDs from both the tables you can get the results from each table according to condition and then perform a UNION on them. So for example
(SELECT `virtuemart_product_id` FROM `#__virtuemart_products` WHERE
`product_special` = 1)
UNION
(SELECT `virtuemart_product_id` FROM
`#__virtuemart_product_badges` WHERE `badge` = 3)
I hope this helps.

How to use having count less than another table

I am having trouble with my MySQL query. I want to show the id FROM one table using left join 3 another table.
What do I want is :
Show id IS NULL in 1 of another table
And having COUNT() < (get column in another table)
I tried this but it is still wrong:
SELECT p.id FROM penerimaan AS p
LEFT JOIN perangkat AS per ON per.id_penerimaan=p.id
LEFT JOIN permintaan AS pa ON pa.id=p.id_permintaan
LEFT JOIN konfirmasi_permintaan AS k ON k.id_permintaan=pa.id
WHERE per.id_penerimaan IS NULL
GROUP BY p.id
HAVING COUNT(per.id_penerimaan) < k.jumlahConfirm //how to get column in another table
ORDER BY p.id ASC
the table I have
table permintaan
id jumlah status
2 3 Confirmed
3 5 Confirmed
-----------------------------------------------
table penerimaan
id id_permintaan date
1 2 2017-07-12
2 3 2017-08-12
-----------------------------------------------
table konfirmasi_permintaan
id id_permintaan jumlahConfirmed
1 2 3
2 3 3
-----------------------------------------------
table perangkat
id id_penerimaan serial type
1 1 766544 SG90D-08-AS
2 1 552411 SLM2008T-EU
3 1 552411 SLM2008T-TU
4 2 561434 SG95-24-AS
I desired result like this
id_penerimaan
2
though id_penerimaan in table perangkat IS NULL but still show, because count(perangkat.id_penerimaan) is 2 in table perangkat less than jumlahConfirm in table konfirmasi_permintaan
Thank you
Removing WHERE per.id_penerimaan seems to solve the problem. You also have to add k.jumlahConfirmed to the SELECT list, because HAVING can only access values in the select list, not columns from the original tables.
SELECT p.id, k.jumlahConfirmed FROM penerimaan AS p
LEFT JOIN perangkat AS per ON per.id_penerimaan=p.id
LEFT JOIN permintaan AS pa ON pa.id=p.id_permintaan
LEFT JOIN konfirmasi_permintaan AS k ON k.id_permintaan=pa.id
GROUP BY p.id
HAVING COUNT(per.id_penerimaan) < k.jumlahConfirmed
DEMO

Select From table name obtained dynamically from the query

I have 3 Tables
campaign1 (TABLE)
id campaign_details
1 'some detail'
campaign2 (TABLE)
id campaign_details
1 'some other detail'
campaign_list (TABLE)
id campaign_table_name
1 'campaign1'
2 'campaign2'
Campaign list table contains the table name of the two tables described above. I want to Select from the Campaign List table and get the record count using the table name i get from this select
For eg.
using select i get campaign1(Table name). Then i run select query on campaign1 to count number of records.
What i'm doing right now is .
-Select from campign_list
-loop through all campaign_table_names and run select query individually
Is there a way to do this using a single query
something like this
select campaign_name,(SELECT COUNT(*) FROM c.campaign_name) as campcount from campaign_list c
SQLFiddle : http://sqlfiddle.com/#!9/b766d/2
It's not possible inside a single query to build it dynamically but it's possible to cheat. Especially if there are only two linked tables.
I've listed two options
left outer join both tables
select campaign_name,
coalesce(c1.campaign_details, c2.campaign_details)
from campaign_list c
left join campaign1 c1 using (id)
left join campaign2 c2 using (id);
union all two different selects
select campaign_name,
campaign_details
from campaign_list c
join campaign1 c1 using (id)
union all
select campaign_name,
campaign_details
from campaign_list c
join campaign2 c2 using (id);
sqlfiddle
Combine your campaign tables to 1 table and add an column named 'type' (int).
campaign_items tables:
item_id item_details item_type
1 'some detail' 1
2 'some detail' 1
3 'some other detail' 2
4 'some other detail' 2
campaign_lists table
campaign_id campaign_name
1 'campaign1'
2 'campaign2'
Then you can use the following select statement:
SELECT campaign_name, (SELECT COUNT(*) FROM campaign_items WHERE item_type = campaign_id) as campaign_count
FROM campaign_lists
Oops, writing took me so long that you got this answered by Colin Raaijmakers already. Well, I'll post my answer anyway in spite of being more or less the same answer. Maybe my elaboration helps you see the problem.
Your problem stems from a bad database design. A database is made to order data and its relations. A CD database holds albums, songs, artists, etc. A business database may hold items, warehouses, sales and so on. Your database holds table names. [... time for thinking :-) ]
(When writing a DBMS you would want to store table names, column names, constraints etc., but I guess I am right supposing that you are not writing a new DBMS.)
So create tables that deal with your actual data. E.g.:
campain_type (id_campain_type, description, ...)
campain (id_campain, id_campain_type, campain_date, ...)
campain_type
id_campain_type description
1 Type A
2 Type B
3 Type C
campain
id_campain id_campain_type date
33 1 2015-06-03
85 2 2015-10-23
97 2 2015-12-01
query
select
ct.description,
(select count(*) from campain c where c.id_campain_type = ct.id_campain_type) as cnt
from campain_type ct;
result
description cnt
Type A 1
Type B 2
Type C 0

Complex mysql query. Return as multiple rows as apposed to single row

I currently have the following SQL query wich retrieves a record from a table and also it's parents and grandparent. The only issue I have is that it's returned as a single record. I would like it return as multiple rows, as it's stored in the database.
Current structure:
comment_id | parent_comment_id
1 3
2 7
3 5
7 11
SQL:
SELECT p3.comment_id as `Grandparent`, p2.comment_id as `Parent`, p1.comment_id as `Child`
FROM comments p1
LEFT JOIN comments p2 on p1.comment_id = p2.parent_comment_id
LEFT JOIN comments p3 on p2.parent_comment_id = p3.comment_id
WHERE p1.comment_id = 1
Current Output (single row):
Grandparent | Parent | Child
5 3 1
Desired Output (separate rows):
comment_id
5
3
1
I am editing some existing mysql code, I do not have the option to convert everything to mysqli or pdo at the moment.
try this:
select comment_id from cm where comment_id = 1
union
select parent_comment_id from cm where comment_id =1
union
select g.parent_comment_id from cm g
join cm p
on p.parent_comment_id = g.comment_id
where p.comment_id = 1;
please verify the logic and make sure it gives you the correct result.
Demo: SQLFiddle

common values b/w fields

This table lists user and item id's
user_id item_id
1 1
1 2
1 3
2 1
2 3
3 1
3 4
3 3
How can I run a query on this table to list all the items that are common between given users.
My guess is, this will need a self join, but I'm not sure.
i am trying this quering but it's returning an error
SELECT *
FROM recs 1
JOIN recs 2 ON 2.user_id='2' AND 2.item_id=1.item_id
WHERE 1.user_id='1'
Try using alias names that start in a letter:
SELECT *
FROM recs r1
JOIN recs r2 ON r2.user_id='2' AND r2.item_id=r1.item_id
WHERE r1.user_id='1'
This returns
user_id item_id
------- -------
1 1
1 3
for your data. Demo on sqlfiddle.
Note: I kept single quotes in the query, because I assume that both IDs in your table are of character type. If that is not the case, remove single quotes around user ID values '1' and '2'.
I want it for n number of users ... a I want the query to return all item_id's that are common among the users
SELECT DISTINCT(r1.item_id)
FROM recs r1
WHERE EXISTS (
SELECT *
FROM recs r2
WHERE r2.item_id=r1.item_id
AND r1.user_id <> r2.user_id
)
Demo #2.