Inner Join 3 tables pl/sql - mysql

Basically i want to inner join 3 tables and the case is understood by the query itself as follows.
Tables:
A has 2 columns column 1 and column 2
B has 2 columns column 3 and column 4
C has 3 columns column 5,column 6 and column 7
Query:
select A.column1, C.Count(C.column6)
from table1 as A inner join table3 as C on A.column2 = C.column5
inner join table2 as B on C.column5 = B.column4 and column3 = 'abcd'
where column7 > NOW() - Interval '30 days'
group by C.column5
order by C.count(column5) desc
But I am getting an error schema C does not exist
Why is this happening? Any mistake with the query?

The issue is that you are using the alias C where you should not, with the count function. This:
C.Count(C.column6)
should be:
Count(C.column6)
and the same change applies in the order by clause (which might be counting the wrong column - should it not be column6?):
order by C.count(column5) desc -> order by count(column6) desc
Also: you should reference all non-aggregated columns in the group by clause, so it should probably be group by A.column1

Related

mysql - how do I use the same table in an inner and outer query?

consider the following table
id
class
Y
1
A
20
1
B
50
1
C
30
1
TOTAL
100
I need to generate a column that is the percentage each class contributes to the effort
something like
select Y/(select Y from table where class = 'TOTAL')
from table
group by id
but how do I pass the id to the inner query?
With aliases you will get something like:
select
t1.Y/(select t2.Y from table1 t2 where t2.class = 'TOTAL')
from table1 t1
group by t1.id
But this will produce the following error (see: DBFIDDLE:
Expression #1 of SELECT list is not in GROUP BY clause and contains
nonaggregated column 'db_1321975282.t1.Y' which is not functionally
dependent on columns in GROUP BY clause; this is incompatible with
sql_mode=only_full_group_by
I think this is what you meant to do, see DBFIDDLE:
select
t1.Y/t2.sumY
from table1 t1
cross join (select sum(y) as sumY from table1 where class='TOTAL') t2
In this query t1,t2 and sumY are aliases.
output:
t1.Y/t2.sumY
0.2000
0.5000
0.3000
1.0000

how to group by a field that has both select and count

I am wondering how to group by a field that has both a select count() and count() statement. I know that we have to put all select fields in group by but it wont let me do so because of the second count() statement in the field.
create table C as(
select a.id, a.date_id,
(select count(b.hits)*1.00 where b.hits >= '9')/count(b.hits) AS percent **<--error here
from A a join B b
on a.id = b.id
group by 1,2,3) with no data primary index(id);
This is my error:
[SQLState HY000] GROUP BY and WITH...BY clauses may not contain
aggregate functions. Error Code: 3625
When i add a select to the second count in the third line only get 1 or 0 which is not right.
`((select count(b.hits)*1.00 where b.hits >= '9')/(select count(b.hits))) AS` percent
Do i need to do a self join instead or is there any way i can just use nested queries?
You need to fix the group by. But, you can probably simplify the query as:
create table C as
select a.id, a.date_id,
avg(b.hits >= 9) as percent
from A a join
B b
on a.id = b.id
group by a.id, a.date_id
with no data primary index(id);
It looks like you only need to group on 2 columns, not 3, plus you shouldn't need a sub-select:
create table C as(
select a.id, a.date_id,
SUM(CASE WHEN b.hits >= '9' THEN 1 ELSE 0 END)/COUNT(b.hits) AS percent
from A a join B b
on a.id = b.id
group by 1,2) with no data primary index(id);

SQL Table Counting and Joining

I have Table A, Column 1.
This table has values such as:
1
2
3
3
4
4
4
5
I have Table B, Column 2.
Which lists certain values, like:
1
3
4
I need a query to Count each unique value in Table A, but ONLY if that value is present in Table B.
So with the above, the end result would be:
1 has a quantity of 1,
3 has a quantity of 2,
and 4 has a quantity of 3.
My only problem is that I do not have this ability. Any help out there?
Based on your question, something like the following should solve your problem.
select b.column1,
count(a.column2)
from tableb as b
inner join tablea as a on b.column1 = a.column2
group by b.column1
Since you wanted only records which are in both tables, I am using an inner join. Then I am just grouping by the ID found in tableb, and getting the count of rows in tablea.
Let me know if you have any problems.
For more information regarding inner join, see : http://www.w3schools.com/sql/sql_join_inner.asp, and for group by, see : http://www.w3schools.com/sql/sql_groupby.asp
I would use an INNER JOIN query with GROUP BY aggregate function
SELECT a.column1,
count(a.column1) as total
FROM tablea a
INNER JOIN tableb b
ON a.column1 = b.column2
GROUP BY a.column1
SELECT column1,COUNT(column1)
FROM table1
WHERE column1 IN
(SELECT DISTINCT column2 FROM table2)
GROUP BY column1
Try this
MsSql
Select Distinct Column1,Count(Column1) Over (Partition by Column1)
From Table1
Where Column1 IN (Select Column2 From Table2)
Fiddle Demo
MySQl
Select Column1,Count(Column1)
From Table1
Where Column1 IN (Select Column2 From Table2)
group by column1
Fiddle Demo

Alternative to UNION clause in Mysql

I have two table :- table a, table b.
table a
---ID---
1
2
3
4
5
7
table b
---ID----
2
3
4
5
6
I have to get Output Like this without UNION Command:-
----ID-----
1
2
3
4
5
6
7
Note: I have one solution with union:-
**select * from a
UNION
select * from b;**
I need alternative to this. please experts suggest.
We need another table with (at least) 2 rows for this:
CREATE TABLE d
( id INT NOT NULL
);
INSERT INTO d
(id)
VALUES
(0), (1) ;
Then, if we want to have only one query, we can use (this is for fun, DO NOT USE in production, that's why we have UNION):
SELECT DISTINCT
COALESCE(aa.id, bb.id) AS id
FROM
d
LEFT JOIN a AS aa ON d.id = 0
LEFT JOIN b AS bb ON d.id = 1
WHERE
COALESCE(aa.id, bb.id) IS NOT NULL
ORDER BY
id ;
Tested at SQLfiddle.com, and for other table combinations:
1 row - 1 row
2 rows - 2 rows
0 rows - 1 row
0 rows - 2 rows
0 rows - 0 rows
try this:
I think it works well in MS-SQL, change it to MySQL if you need, but MYSql doesnot support full outer join! Good luck
SELECT (
CASE
WHEN b.ID IS NULL
THEN a.ID
WHEN b.ID=a.ID
THEN b.ID
ELSE b.ID
END)
FROM
(SELECT ID FROM table2
)b
FULL OUTER JOIN
(SELECT ID FROM table1
) a
ON a.ID=b.ID
and play around with the query
Fiddle: http://sqlfiddle.com/#!3/c657d/13
And here is the MYSQL version:
SELECT DISTINCT COALESCE(t1.id, t2.id) id
FROM
(
SELECT TABLE_NAME <> 'table_a' n
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = SCHEMA()
AND TABLE_NAME IN('table_a', 'table_b')
) t LEFT JOIN table_a t1
ON t.n = 0 LEFT JOIN table_b t2
ON t.n = 1
Working fiddle: http://sqlfiddle.com/#!2/c657d8/34
I don't know why you are avoiding UNION but you can do like following
CREATE TABLE temp_ids(ID INT);
INSERT INTO temp_ids SELECT ID FROM a;
INSERT INTO temp_ids SELECT ID FROM b;
SELECT DISTINCT ID FROM temp_ids;
Try a full outer join and filter the NULL values.
As an abstract exercise (if this is an interview question we expect a kickback!) one ugly, innefficient solution would be to create a cartesian product and filter the unique values:
SELECT DISTINCT IF(a<>b, b.id, a.id)
FROM a, b
ORDER BY 1
;
Use FULL OUTER JOIN, like this:
SELECT CASE
WHEN t1.id IS NULL THEN t2.id
ELSE t1.id
END AS id
FROM t1
FULL OUTER JOIN t2
ON t1.id = t2.id
ORDER BY id
Note: Mysql does not support full outer joins.
Working demo: http://sqlfiddle.com/#!6/b7684/10

Selecting two rows in a table which have the same data for a particular column

There is a column in a table(contracts) called service location. I have to show all the rows where the service locations matches any other row in the table.
Table Example
A B C
1 2 3
3 2 1
2 5 3
I require a query where the first and second rows will be returned based on a comparison on the second column. I am assuming I will need to use a HAVING COUNT(B) > 1
I came up with this
SELECT `contract_number`
FROM `contracts`
WHERE `import_id` = 'fe508764-54a9-41f7-b36e-50ebfd95971b'
GROUP BY `service_location_id`
HAVING COUNT(`service_location_id` ) >1
But it doesn't generate what I exactly need.
Having would do it, but you would need to use it like this
SELECT *
FROM Contracts
INNER JOIN
( SELECT B
FROM Contracts
GROUP BY B
HAVING COUNT(*) > 1 -- MORE THAN ONE ROW WITH THE SAME VALUE
) dupe
ON dupe.B = Contracts.B
Depending in your indexing you may find a self join performs better though:
SELECT DISTINCT t1.*
FROM contracts t1
INNER JOIN contract` t2
ON t1.B = t2.B
AND t1.A <> t2.A
SELECT *
FROM sheet1
WHERE C
IN (
SELECT C
FROM sheet1
GROUP BY C
HAVING COUNT( C ) >1
)
ORDER BY C
LIMIT 0 , 5000