Both queries use the same table (here: test)
First query:
SELECT `test` as t1, COUNT( * ) as t2
FROM `test_table`
WHERE `test` > 5
GROUP BY `test`
returns result in form
--------------------------------------------------
| t1 | t2 |
--------------------------------------------------
| 6 | 2 |
--------------------------------------------------
| 8 | 7 |
--------------------------------------------------
Second query:
SELECT TRUNCATE(((num1/num2) * 100),3) as t3
FROM
(SELECT COUNT( * ) as num1
FROM `test_table`
WHERE test > 5
group by `test`) a,
(SELECT COUNT( * ) as num2
FROM `test_table`
WHERE test > 5) b
returns result in form
--------------------------------------------------
| t3 |
--------------------------------------------------
| 40.456% |
--------------------------------------------------
| 59.544% |
--------------------------------------------------
What I would like to have is:
--------------------------------------------------
| t1 | t2 | t3 |
--------------------------------------------------
| 6 | 2 | 40.456% |
--------------------------------------------------
| 8 | 7 | 59.544% |
--------------------------------------------------
How can I do it ? Union puts the t3 results below t1 t2, perhaps join statement ? But join on what ? Or can I make a one query from these two which selects all the data?
Using subquery in the select makes it quite readable
DROP TABLE IF EXISTS TEST_TABLE;
CREATE TABLE TEST_TABLE(TEST INT);
INSERT INTO TEST_TABLE VALUES
(6),(6),
(8),(8),(8),(8),(8),(8),(8);
SELECT `test` as t1, COUNT(*) as t2,
TRUNCATE(COUNT(*) / (SELECT COUNT(*) FROM TEST_TABLE WHERE TEST > 5) * 100,3) AS T3
FROM `test_table`
WHERE `test` > 5
GROUP BY `test`
Result
+------+----+--------+
| t1 | t2 | T3 |
+------+----+--------+
| 6 | 2 | 22.222 |
| 8 | 7 | 77.777 |
+------+----+--------+
2 rows in set (0.00 sec)
This can be done with a few modifications of your second query:
SELECT a.t1, num1 as t2, TRUNCATE(((num1/num2) * 100),3) as t3
FROM
(SELECT `test` as t1, COUNT( * ) as num1
FROM `test_table`
WHERE test > 5
group by `test`) a,
(SELECT COUNT( * ) as num2
FROM `test_table`
WHERE test > 5) b
SELECT
Z.t1, Z.t2, Z1.t3
FROM
(SELECT
`test` AS t1, COUNT(*) AS t2
FROM
`test_table`
WHERE
`test` > 5
GROUP BY `test`) Z
INNER JOIN
(SELECT
t1, TRUNCATE(((num1 / num2) * 100), 3) AS t3
FROM
(SELECT
test t1, COUNT(*) AS num1
FROM
`test_table`
WHERE
test > 5
GROUP BY `test`) a, (SELECT
COUNT(*) AS num2
FROM
`test_table`
WHERE
test > 5) b) Z1 ON Z.t1 = Z1.t1;
Try above code.
Hope this will help you.
The way it is structured in your example you should be able to join them on test_table.test (the Field you are using Group By on)
Related
for an mass edit function I need to load the parents of multiple objects.
Doing this with single querys would kill the db. I'm using MySQL 5.7 My table is build like this:
CREATE TABLE `testtable` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`content` text,
`parentid` bigint(20) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8
INSERT INTO testtable(`id`, `content`, `parentid`)
VALUES(1, 'parentA1', 0),(5, 'parentA2', 1),(3, 'childA', 2),
(4, 'parentB', 0),(5, 'childB', 4);
For single object querys I use this statement to get all parents:
SELECT t.id, t.content, #pid := t.parentid AS parentid
FROM (SELECT * FROM Table1 order by id DESC) t
JOIN (SELECT #pid := 3) tmp
WHERE t.id = #pid
But I have absolutly no clue how this could work for multiple object at once without using union.
My whised ouput should look like this:
id | content | parentid | searchingChildID
1 | parentA1| 0 | 3
2 | parentA2| 1 | 3
3 | childA | 2 | 3
4 | parentB | 0 | 5
5 | childB | 4 | 5
Thanks in advance!
If you are running MySQL 8.0, this is a typical use case for a recursive query. Say you want all parents of objects 3 and 4, you can do:
with recursive cte as (
select t.id as originalid, t.* from table1 where id in (3, 4)
union all
select c.originalid, t.*
from cte c
inner join table1 t on t.id = c.parentid
)
select * from cte
for an mass edit function I need to load the parents of multiple objects.
For this operation, I would expect:
id | content | parentid | ultimateparent
1 | parentA1| 0 | 0
2 | parentA2| 1 | 0
3 | childA | 2 | 0
4 | parentB | 0 | 0
5 | childB | 4 | 0
Because 0 is the ultimate parent of all the rows. If you know the maximum depth, you can use left joins in pre-8 versions of MySQL:
select t1.*, coalesce(t3.parentid, t2.parentid, t1.parentid) as ultimateparent
from testtable t1 left join
testtable t2
on t2.id = t1.parentid left join
testtable t3
on t3.id = t2.parentid
You can trivially extend this with more left joins to handle deeper levels of parentage.
If 0 really means "no parent" (which is an odd choice when NULL is available) then you would seem to want:
id | content | parentid | ultimateparent
1 | parentA1| 0 | 1
2 | parentA2| 1 | 1
3 | childA | 2 | 1
4 | parentB | 0 | 4
5 | childB | 4 | 4
Then you can actually just tweak the above query to:
select t1.*, coalesce(t3.id, t2.id, t1.id) as ultimateparent
from testtable t1 left join
testtable t2
on t2.id = t1.parentid left join
testtable t3
on t3.id = t2.parentid;
Here is a db<>fiddle.
You can get the maximum child for each parent as well (although that seems quite arbitrary). In pre-8.0 versions of MySQL, variables are the simplest approach:
select t1.*,
(#max_child := if(#up = ultimateparent, #max_child,
if(#up := ultimateparent, id, id)
)
) as max_childid
from (select t1.*, coalesce(t3.id, t2.id, t1.id) as ultimateparent
from testtable t1 left join
testtable t2
on t2.id = t1.parentid left join
testtable t3
on t3.id = t2.parentid
order by ultimateparent, id desc
) t1 cross join
(select #up := -1, #max_child := -1) params;
I have 2 tables with similar column, and i want to join them so i can sort them out together.
select * from (
(select * from table_1)
union all
(select * from table_2 )
) t order by id column_1;
And
Result
How do I show table_1 row only when there's already a duplicate in table_2, like this ?
You can use not exists in the where clause when you select from table_2:
select * from table_1
union all
select t2.* from table_2 t2
where not exists (select 1 from table_1 t1 where t1.colum_1 = t2.colum_1)
order by colum_1
There is no need for subqueries.
The order by clause operates on the result of the union.
See the demo.
Results:
> colum_1 | column_2
> :------ | -------:
> A | 1
> B | 1
> C | 1
> D | 2
> E | 2
I have a 2 tables that looks like this
How can I call the same column wihout duplicating it
TYSM for help
Please try below mentioned Query:
select distinct t2.data,t1.key,t1.data from t1.table1 JOIN table as t2 ON t1.key = t2.key
You could assign a row number using a variable to t2 then join to t1 supressing the output of the t1.key.
for example
drop table if exists t1,t2;
create table t1 (id int);
create table t2 (id int, name varchar(2));
insert into t1 values(1),(2),(3),(4);
insert into t2 values(1,'s1'),(1,'s2'),(2,'s3'),(3,'s4'),(4,'s5');
select s.id, s.name,
case when s.rn = 1 then s.rn
else ''
end as something
from t1
join
(
select t2.id,t2.name,
if(t2.id <> #p, #rn:=1,#rn:=#rn+1) rn,
#p:=t2.id
from t2,(select #rn:=0,#p:=0) r
) s on t1.id = s.id
order by t1.id, s.name
Result
+------+------+-----------+
| id | name | something |
+------+------+-----------+
| 1 | s1 | 1 |
| 1 | s2 | |
| 2 | s3 | 1 |
| 3 | s4 | 1 |
| 4 | s5 | 1 |
+------+------+-----------+
5 rows in set (0.00 sec)
I have two tables that I would like to display as a single result, using UNION or other technique.
The ID field relates both tables.
The second table has one field missing, so that missing value should be assumed from the first table.
The sample code below works, but is very slow for large datasets.
Is there any solution more efficient?
T1: T2:
+----+-------+--------+ +----+------+
| id | name | town | | id | name |
+----+-------+--------+ +----+------+
| 1 | Alice | London | | 1 | Bob |
| 2 | Alan | Zurich | +----+------+
+----+-------+--------+
Desired result:
+----+-------+--------+
| id | name | town |
+----+-------+--------+
| 1 | Alice | London |
| 2 | Alan | Zurich |
| 1 | Bob | London |
+----+-------+--------+
Sample code:
with T1 as
(
select * from
(
values
(1,'Alice','London') ,
(2,'Alan','Zurich')
) as t (id,name,town)
), T2 as
(
select * from
(
values
(1,'Bob')
) as t (id,name)
), T2WithTown as
(
select t2.id,t2.name,t1.town from T2
inner join T1 on t2.id=t1.id
)
select id,name,town from T1
union
select id,name,town from T2WithTown
The sample data shows both tables have distinct values. So I will prefer UNION ALL
Select ID, Name, Town From T1
UNION ALL
select T2.ID, T2.Name, T1.Town
from T1
INNER JOIN T2 on T2.id = T1.id
Just like this:
with T1 as
(
select * from
(
values
(1,'Alice','London') ,
(2,'Alan','Zurich')
) as t (id,name,town)
), T2 as
(
select * from
(
values
(1,'Bob')
) as t (id,name)
), T2WithTown as
(
select t2.id,t2.name,t1.town from T2
inner join T1 on t2.id=t1.id
)
select id,name,town from T1
union
select T2.id, T2.name, T1.town
from T1
inner join T2 on T2.id = T1.id
select id,name, town from t1
union
select id,name, (select top 1 town from t1 where t1.id=t2.id) from t2
I want to know is it possible to do if I have 4 number as below
1,2,3,4
In my data base have data exists as below
1,2,3,5,6,7
How can I query database and return 4 in 1 query
Please advise
CREATE TABLE `example` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
INSERT INTO example VALUES (1),(2),(3),(5),(6),(7);
SELECT t2.id FROM example AS t1
RIGHT JOIN (
SELECT 1 AS id UNION
SELECT 2 AS id UNION
SELECT 3 AS id UNION
SELECT 4 AS id
) AS t2
ON t1.id = t2.id
WHERE t1.id IS NULL;
+----+
| id |
+----+
| 4 |
+----+
Or use a temporary table:
CREATE TEMPORARY TABLE `tmp` (
`id` int(11) DEFAULT NULL
) ENGINE=InnoDB;
INSERT INTO tmp VALUES (4);
SELECT t2.id FROM example AS t1
RIGHT JOIN tmp AS t2
ON t1.id = t2.id
WHERE t1.id IS NULL;
To see what's happening, switch things around a bit:
SELECT t1.id, t2.id FROM example AS t1
RIGHT JOIN (
SELECT 1 AS id UNION
SELECT 2 AS id UNION
SELECT 3 AS id UNION
SELECT 4 AS id
) AS t2
ON t1.id = t2.id;
+------+----+
| id | id |
+------+----+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| NULL | 4 |
+------+----+
SELECT id FROM
( SELECT 1 AS id UNION
SELECT 2 UNION
SELECT 3 UNION
SELECT 4
) AS TBL1
WHERE id NOT IN (SELECT id FROM thetable)