Given the following DataBase:
CREATE TABLE album ( id int );
INSERT INTO album (id) VALUES
(1),
(2),
(3),
(4);
CREATE TABLE icon_album ( albumID int, current int );
INSERT INTO icon_album (albumID, current) VALUES
(1, 1),
(1, 1),
(2, 1),
(2, 0),
(3, 0),
(3, 0);
I would like to get the following result
albums: id status
1 1
2 0
3 0
4 0
What is the MySql query that would give me the correct result?
P.S. 1: This is my second question for this problem. This first question did not yield a working solution
Is this what you're looking for?
SELECT a.id, IF(i.current IS NULL, 0, current) AS status
FROM album a LEFT JOIN
(
SELECT albumID, MIN(current) AS current
FROM icon_album
GROUP BY albumID
) i ON a.id = i.albumID
Try Like this
"SELECT albumID AS id, if(SUM(current)>1,1,0) AS status FROM icon_album GROUP BY albumID"
Related
I have the following tables:
create table loans
(
id int null,
status int null,
user_id int null
);
INSERT INTO loans VALUES (1, 1, 1);
INSERT INTO loans VALUES (2, 0, 1);
INSERT INTO loans VALUES (3, 1, 1);
create table deals
(
id int null,
status int null,
user_id int null
);
INSERT INTO deals VALUES (2, 0, 1);
INSERT INTO deals VALUES (3, 0, 1);
create table listings
(
id int null,
status int null,
user_id int null
);
INSERT INTO listings VALUES (1, 1, 1);
INSERT INTO listings VALUES (2, 1, 1);
INSERT INTO listings VALUES (3, 1, 1);
And have the following SQL:
SELECT COUNT(*) AS active_items
FROM loans
LEFT JOIN deals ON deals.user_id = 1
LEFT JOIN listings ON listings.user_id = 1
WHERE
loans.status = 1
AND deals.status = 1
AND listings.status = 1
AND loans.user_id = 1
The goal is to count all the rows where each table item has a status of 1, leaving out any that have a status of 0. My query which I have made seems to only return 0 all the time and I do not understand why? How can I query the database so I can find each loan, deal and listing which has a status of 1 and returns in one total called active_items? Why does my query not work?
DB Fiddle: https://www.db-fiddle.com/f/g9CoA9CdDujqzG4ZpgmJXh/1
The output for active_items is expected to be 5.
Don't use JOIN for this, since you're not relating the tables to each other. Just do 3 separate queries and add the counts.
SELECT SUM(count) AS total
FROM (
SELECT COUNT(*) AS count
FROM loans
WHERE user_id = 1 AND status = 1
UNION ALL
SELECT COUNT(*) AS count
FROM deals
WHERE user_id = 1 AND status = 1
UNION ALL
SELECT COUNT(*)
FROM listings
WHERE user_id = 1 AND status = 1
) AS x
DEMO
It is not 100% clear to me what you are trying to check.
But if I understand it correctly, I think the problem you have, is you are only checking for the user_id = 1, which might not have status 1 in all the tables (I really can't be sure without seeing your data).
I think you want to do something like:
SELECT COUNT(*) AS active_items
FROM loans
INNER JOIN deals ON deals.user_id = loans.user_id
INNER JOIN listings ON listings.user_id = loans.user_id
WHERE
loans.status = 1
AND deals.status = 1
AND listings.status = 1
There are three related tables:
operations (id, name)
pricelists (id, operations_id (link to operations table), cost)
accounting (id, pricelists_id (link to pricelists table), quantity)
How to get table, like
NAME SUMMARY_COST SUMMARY_QUANTITY
milling result of 2*750 2
threading result of 1*444 1
... ... ...
overall 2*750+1*444+... 2+1+...
I trying to group for two tables at a start:
select operations.name, sum(pricelists.cost) total
from operations
left join pricelists on pricelists.operations_id*accounting_quantity = operations.id*accounting.quantity
group by operations.id
but it is not worked yet
A little database:
CREATE TABLE operations (id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR (100));
CREATE TABLE pricelists (id INT PRIMARY KEY, operations_id INT NOT NULL, cost DECIMAL(10,2),
FOREIGN KEY (operations_id) REFERENCES operations (id));
CREATE TABLE accounting (id INT PRIMARY KEY, pricelists_id INT NOT NULL, quantity INT,
FOREIGN KEY (pricelists_id) REFERENCES pricelists (id));
INSERT INTO operations (name) VALUES
('milling'),
('threading'),
('grinding'),
('welding'),
('brazing'),
('soldering'),
('riveting');
INSERT INTO pricelists (id, operations_id, cost) VALUES
(1, 2, 750),
(2, 1, 444),
(3, 3, 123),
(4, 4, 450),
(5, 5, 375),
(6, 6, 250),
(7, 7, 232);
INSERT INTO accounting (id, pricelists_id, quantity) VALUES
(1, 7, 2),
(2, 2, 5),
(3, 4, 2),
(4, 1, 1),
(5, 3, 4);
Consder:
select o.name, sum(a.quantity * pl.cost) total, sum(a.quantity) quantity
from operations o
left join pricelists pl on pl.operations_id = o.id
left join accounting a on a.pricelists_id = pl.id
group by o.name
You can generate the summary row by just adding with rollup at the very end of the query.
I have tables (bar, baz) which have 1 or more rows relating to another table (foo). When I join both bar & baz to foo I get results for each row of each table.
http://sqlfiddle.com/#!9/1c13f2/1/0
CREATE TABLE foo (`id` int, `value` varchar(5));
INSERT INTO foo (`id`, `value`) VALUES
(1, 'two'),
(2, 'two'),
(3, 'one');
CREATE TABLE bar (`id` int, `foo_id` int, `value` int);
INSERT INTO bar (`id`, `foo_id`, `value`) VALUES
(1, 1, 1),
(2, 1, 1),
(3, 2, 1),
(4, 2, 1),
(5, 3, 1);
CREATE TABLE baz (`id` int, `foo_id` int, `value` int);
INSERT INTO baz (`id`, `foo_id`, `value`) VALUES
(1, 1, 1),
(2, 1, 1),
(3, 2, 1),
(4, 2, 1),
(5, 3, 1);
The query:
SELECT foo.value, SUM(bar.value), SUM(baz.value)
FROM foo
JOIN bar ON bar.foo_id = foo.id
JOIN baz ON baz.foo_id = foo.id
GROUP BY foo.id
Result:
value SUM(bar.value) SUM(baz.value)
two 4 4
two 4 4
one 1 1
Expected result:
value SUM(bar.value) SUM(baz.value)
two 2 2
two 2 2
one 1 1
The result is the expected behavior, from a cross (semi-Cartesian) product, multiple rows from bar matched to multiple rows from baz.
To avoid this, we can pre-aggregate counts from bar and baz, and then do the join.
Also consider, what result is expected when there are matching rows in bar but no matching rows in baz. Do we want to return the total from bar? With the current query, we wouldn't get total from bar. (In the example data, consider what the query will return after row id=5 is deleted from baz.)
I'd write the query like this:
SELECT foo.value
, IFNULL( r.tot_bar_value ,0) AS tot_bar_value
, IFNULL( z.tot_baz_value ,0) AS tot_baz_value
FROM foo
LEFT
JOIN ( -- aggregate total from bar
SELECT bar.foo_id
, SUM(bar.value) AS tot_bar_value
FROM bar
GROUP BY bar.foo_id
) r
ON r.foo_id = foo.id
LEFT
JOIN ( -- aggregate total from bar
SELECT baz.foo_id
, SUM(baz.value) AS tot_baz_value
FROM baz
GROUP BY baz.foo_id
) z
ON z.foo_id = foo.id
Note that we are using outer joins, to handle the case when there not matching rows in either bar or baz.
For testing, we can run separately just the SELECT query inside the parens, to see what is returned.
I have 3 related tables. Adults, Children and AC. Adults contains an INT column to count high school seniors. Children contains a column with year of highs school graduation. AC links the adult.id to the children.id.
CREATE TABLE adults (
id INT,
name VARCHAR(10),
seniors INT DEFAULT 0
) ;
INSERT INTO adults (id, name) VALUES
(1, 'adam'),
(2, 'bob');
CREATE TABLE children (
id INT,
name VARCHAR(10),
grad VARCHAR(4)
) ;
INSERT INTO children (id, name, grad) VALUES
(1, 'sally', '2016'),
(2, 'johnny', '2017'),
(3, 'eric', '2016'),
(4, 'billy', '2016'),
(5, 'rachel', '2016');
CREATE TABLE pc (
id INT,
a_id INT,
c_id INT
) ;
INSERT INTO pc (id, a_id, c_id) VALUES
(1, 1, 1),
(2, 1, 2),
(3, 1, 3),
(4, 2, 3),
(5, 2, 2);
SQLFiddle: http://sqlfiddle.com/#!2/89281e
So I want to update adults.seniors to the count of '2016' children they're linked to. So adult #1 would be "2" (sally and eric), and adult #2 "1" (eric).
The real data will be run across 25,000+ children being matched up to 40,000+ parents with a row count on the "pc" table above 3,000,000 rows - so looking for efficiency. I started working down this path but a) it's not working for obvious reasons and b) I doubt it would be efficient...
UPDATE adults a SET
seniors = (
SELECT p.a_id, count(*)
FROM pc p
INNER JOIN children c ON c.id = p.c_id
WHERE c.grad = '2016'
GROUP BY p.c_id)
WHERE p.a_id = a.id;
I'm thinking there has to be a better way of doing this with joins but can't seem to wrap my head around it.
You should be looking for this update statement:
UPDATE adults a
JOIN
(SELECT
p.a_id, COUNT(*) childrencount
FROM
pc p
INNER JOIN children c ON c.id = p.c_id
WHERE
c.grad = '2016'
GROUP BY p.a_id) c ON (a.id = c.a_id)
SET
seniors = c.childrencount;
I have the following DDLs...
CREATE TABLE IF NOT EXISTS `product` (
`id_product` int(10),
`id_manufacturer` int(10)
);
INSERT INTO `product` (`id_product`, `id_manufacturer`) VALUES
(1,1),
(2,1),
(3,2),
(4,1),
(5,2);
CREATE TABLE IF NOT EXISTS `feature_product` (
`id_feature` int(10),
`id_product` int(10),
`id_feature_value` int(10)
);
INSERT INTO `feature_product` (`id_feature`, `id_product`, `id_feature_value`) VALUES
(5, 1, 9),
(5, 2, 9),
(5, 3, 10),
(5, 4, 10),
(7, 5, 10);
http://sqlfiddle.com/#!2/cbe05/1/0
Can you explain me please, how I can get - all Products with the same Manufacturer and the same Feature_value?
Now (in project) I do it with 2 additional SELECT's (for getting id_manufacturer and id_feature_value), but maybe there are more correct (and fast) way?
Thanks for your time and sorry for my English)
I need too see result like this:
id_product |
-----------|
1 |
2 |
only this 2 products have same manufacturer and (at the same time) same feature value
Just use GROUP_CONCAT:
SELECT GROUP_CONCAT(p.id_product SEPARATOR '\n') AS Products
FROM product p
INNER JOIN feature_product fp ON (p.id_product = fp.id_product AND fp.id_feature = 5)
GROUP BY p.id_manufacturer, fp.id_feature_value
HAVING COUNT(p.id_manufacturer) > 1
AND COUNT(fp.id_feature_value)>1;
This will give you the list of Products having multiple Manufacturer Id and Feature Value in a single line, separated by a newline character. You can change the separator as your requirement.
Here is the SQL Fiddle link:
http://sqlfiddle.com/#!2/cbe05/70