using latest mariaDB release, I have the following table structure (trimmed for example)
Table A
+--------+------+
| id |name |
+--------+------+
| 1 | Bob |
| 2 | Jane |
+--------+------+
Table B
+--------+------+
| id |city |
+--------+------+
| 1 | abc |
| 2 | def |
| 3 | ghi |
| 4 | jkl |
+--------+------+
Pivot Table
+-----------+-----------+
| tableA_id | tableB_id |
+-----------+-----------+
| 1 | 1 |
| 1 | 3 |
| 2 | 3 |
| 2 | 4 |
+-----------+-----------+
is there a way to make it go from this output or will that need to be done php?
+--------+------+-------+
| id |name | city1 |
+--------+------+-------+
| 1 | Bob | abc |
| 1 | Bob | ghi |
| 2 | Jane | ghi |
| 2 | Jane | jkl |
+--------+------+-------+
to this:
+--------+------+----------+
| id |name | cities |
+--------+------+----------+
| 1 | Bob | abc ghi |
| 2 | Jane | ghi jkl |
+--------+------+----------+
using the below query currently
SELECT c.id, c.city1, p.id pid, p.first_name FROM city c
INNER JOIN pivot_tablet piv ON c.id = piv.city_id
INNER JOIN person p ON p.id = piv.person_id
use group_concat()
SELECT p.id,p.first_name,group_concat(c.city1 SEPARATOR ' ') as cities,
FROM pivot_tablet piv inner join city ON c.id = piv.city_id
INNER JOIN person p ON p.id = piv.person_id
group by p.id, p.first_name
create table #temp (row1 int,row2 int,row3 int,row4 varchar(20),row5 int,row6 varchar(20))
insert into #temp
select * from table3 join Table1 on Table1.id=Table3.idTable1 join table2 on table2.id = table3.idtable2
select row1,row4,
row6
= STUFF((
SELECT ', ' + t2.row6
FROM #temp t2
WHERE t1.row1 = t2.row1
FOR XML PATH('')
),1, 2, '')
FROM #temp t1
GROUP BY t1.row1,t1.row4
Related
I got 3 tables
| ID | Name |
|:---- |:------:|
| 1 | Brie |
| 2 | Ray |
| 3 | James |
Table2
| ID | Q_id | Q_no | ans |
|:---- |:------:| -----:|----:|
| 1 | 2304. | 1 | A |
| 1 | 2304. | 2 | A |
| 1 | 2305. | 1 | C |
| 2 | 2304. | 2 | A |
| 2 | 2305. | 1 | C |
| 3 | 2304. | 1 | A |
| 3 | 2305. | 2 | D |
Table3
| Q_id | Q_no | correct_ans |
|:------:| -----:|------------:|
| 2304. | 1 | A |
| 2304. | 2 | B |
| 2305. | 1 | C |
| 2305. | 2 | D |
I need to print a table with ID, name and count of ans in table 2 where ans matches with correct answer from table 3
| ID | Name | ans_count |
|:---- |:------:| ----------:|
| 1 | Brie | 2 |
| 2 | Ray | 1 |
| 3 | James | 2 |
Select t1.ID, Name, count(t2.ans) as ans_count
from Table1 t1
join Table2 t2 on t1.ID=t2.ID
join Table3 t3 on t2.Q_id=t3.Q_id
where t2.ans=t3.correct.ans and t2.q_no=t3.q_no
group by t1.ID
order by t1.ID
Where am I doing it wrong? Sorry I am new to SQL.
You should always link the tables, with all colums that match
AND the GROUP By should contain all columns that have no aggregation function
SELECT t1.ID,t1.`Name`,COUNT(*) as correct_answers
FROM table1 t1
JOIN table2 t2 ON t1.ID = t2.ID
JOIN table3 t3 ON t2.`Q_id` = t3.`Q_id` AND t2.`Q_no` = t3.`Q_no`
WHERE t3.`correct_ans` = t2.`ans`
GROUP BY t1.ID,t1.`Name`
order by t1.ID
ID
Name
correct_answers
1
Brie
2
2
Ray
1
3
James
2
fiddle
Its still not clear what you are after, but this corrects the obvious issue with the query.
Select t1.ID, Name, count(*) as ans_count
from Table1 t1
join Table2 t2 on t1.ID=t2.ID
join Table3 t3 on t2.Q_id=t3.Q_id
where t2.ans=t3.correct.ans
group by t1.ID, t1.Name ///<---------------
order by t1.ID
I think you need to group by Id and Name
My problem is that i have 4 tables, that i want to combine. Table1 has Tickets, Table2 with users, Table 3 with admins and Table4 with files. My Select was woring great when i had only 3 tables, without files, my select back then was something like this
SELECT
Table1.TicketNumber,
Count(Table1.TicketNumber) as "number of tickets",
Table2.UserName,
Table3.AdminName
FROM Table1
inner join
table2 on table1.ID_U=table2.ID
inner join
table3 on table1.ID_A=table3.ID
GROUP BY Table1.TicketNumber
Then i decided to add to my select another table(Table4), from which i would sum number of files for corresponding Ticket, and my Select is something like this:
SELECT
Table1.TicketNumber ,
Table1.count,
Table4.count
FROM
( SELECT TicketNumber,
count(*) AS count
FROM Table1
GROUP BY TicketNumber
)Table1
LEFT JOIN
( SELECT TickerNumber,
count(*) as count
FROM Table2
GROUP BY TicketNumber
) Table2 ON Table1.Name=Table2.Name
My problem is when i try to in somehow merge these two selects to get all that i want, i get syntax error in my INNER JOIN that Table1.ID_U doesnt exist.
Here is simplified struct of my Tables
Table1 Table 2/3
+----+--------------+------+------+----------+ +----+----------------+
| ID | TicketNumber | ID_U | ID_A | SomeData | | ID | User/Admin Name|
+----+--------------+------+------+----------+ +----+----------------+
| 0 | T001 | 1 | 1 | blah | | 0 | Name |
| 1 | T002 | 2 | 3 | blah | | 1 | Name |
| 2 | T002 | 2 | 3 | blah | | 2 | Name |
| 3 | T003 | 2 | 2 | blah | | 3 | Name |
| 4 | T004 | 3 | 1 | blah | | 4 | Name |
+----+--------------+------+------+----------+ +----+----------------+
My Table4
+----+------------+----------+
| ID | TicketName | FileName |
+----+------------+----------+
| 0 | T002 | Name |
| 1 | T002 | Name |
| 2 | T003 | Name |
| 3 | T004 | Name |
| 4 | T007 | Name |
+----+------------+----------+
My goal is to reach Select that looks like this
+----+--------------+----------------+--------------+----------+-----------+
| ID | TicketNumber | HowManyTickets | HowManyFiles | User | Admin |
+----+--------------+----------------+--------------+----------+-----------+
| 0 | T001 | 1 | 0 | UserName | AdminName |
| 1 | T002 | 2 | 2 | UserName | AdminName |
| 2 | T003 | 1 | 1 | UserName | AdminName |
| 3 | T004 | 5 | 1 | UserName | AdminName |
+----+--------------+----------------+--------------+----------+-----------+
Unfortunaly all i am capable of doing is either getting
TicketNumber, HowManyTickets, HowManyFiles,
or
TicketNumber, HowManyTickets, User, Admin
It seems your result ID is generated since its not anymore the same to your TicketID.
Here's my suggestion, using row_number() to generate the ID, then use sum() aggregation function to group your ticketNumber. left join will give you 0 result on your Ticket T001.
select row_number() over (order by t1.TicketNumber) as ID
, t1.TicketNumber
, sum(case when coalesce(t1.TicketNumber, '') = '' then 0 else 1 end) as HowManyTickets
, coalesce(t4.numFiles, 0) as HowManyFiles
, t2.Name as USER
, t3.Name as Admin
from table1 t1
left join table2 t2 on t2.ID = t1.ID_U
left join table3 t3 on t3.ID = t1.ID_A
left join
(select count(1) as numFiles, TicketNumber from table4 group by TicketNumber) t4 on t4.TicketNumber = t1.TicketNumber
group by t1.TicketNumber, t4.numFiles
I want to merge two tables that I have, both of them have the same name in them. Going to use it so corresponding ticket number can have few requests, and also few files in it
Table1 that is my main table Table 2 that I want to join
+----+------+-------+-------+ +----+------+-------+
| ID | Name | Info1 | Info2 | | ID | Name | Info1 |
+----+------+-------+-------+ +----+------+-------+
| 0 | L01 | blah | blah | | 0 | L01 | blah |
| 1 | L02 | blah2 | blah2 | | 1 | L01 | blah |
| 2 | L02 | blah3 | blah3 | | 2 | L03 | blah |
| 3 | L03 | Blah3 | blah3 | | 3 | L04 | blah |
| 4 | L04 | Blah4 | blah4 | | 4 | L04 | blah |
+----+------+-------+-------+ +----+------+-------+
Then I use select to group it like this
+------+-------------+
| Name | Count(Name) |
+------+-------------+
| L01 | 1 |
| L02 | 2 |
| L03 | 1 |
| L04 | 1 |
+------+-------------+
And my goal is to make something like this
+------+-------------+--------------------+
| Name | Count(Name) | Count(table2.Name) |
+------+-------------+--------------------+
| L01 | 1 | 2 |
| L02 | 2 | 0 |
| L03 | 1 | 1 |
| L04 | 1 | 2 |
+------+-------------+--------------------+
any suggestions? code I tried so far on my existing project, `NR_REKLAMACJI is my Name from Table 1, this code was working when I only counted the number of Names in this particular table:
SELECT
`NR_REKLAMACJI`,
COUNT(NR_REKLAMACJI) AS 'ilosc reklamowanego towaru',
CONCAT(klienci.IMIE, ' ', klienci.NAZWISKO) AS 'Klient',
CONCAT(users.IMIE, ' ', users.NAZWISKO) AS 'Osoba zajmująca się',
DOK_FV,
klienci.NAZWA_FIRMY,
DATA
FROM
`rtransportowa`
INNER JOIN klienci ON ID_R = klienci.ID_KLIENTA
INNER JOIN users ON ID_U = users.ID_USER
group by
NR_REKLAMACJI
You can join two subqueries result and construct a result as you want on basis of a left-join:
SELECT t1.`Name` as `Name`, t1.count AS `count(Name)`, IFNULL(t2.count, 0) AS `count(table2.Name)`
FROM (SELECT `Name`, count(*) AS count FROM tbl1 GROUP BY `Name`) t1
LEFT JOIN
(SELECT `Name`, count(*) AS count FROM tbl2 GROUP BY `Name`) t2 ON t1.`Name` = t2.`Name`;
You can use joining two table as one table
select tb1.Name,
CASE WHEN tb1_Count_Name IS NULL THEN '0' ELSE tb1_Count_Name END AS tb1_Count_Name,
CASE WHEN tb2_Count_Name IS NULL THEN '0'ELSE tb2_Count_Name END AS tb2_Count_Name from
(select DISTINCT Name as Name,Count(Name) as tb1_Count_Name from [dbo].[Table_1] as t1 group by t1.Name) as tb1 left join
(select DISTINCT Name as Name ,Count(Name) as tb2_Count_Name from [dbo].[Table_2]as t2 group by t2.Name )as tb2 on tb1.Name=tb2.Name
I have two tables like table A and table B. and columns names in both table A and B which are
A B
------------------------ -----------------------
| ID | sID | qID | fID | | xmlText | sID | qID |
------------------------ -----------------------
| 1 | 1 | 1 | 213 | | xml | 1 | 1 |
| 2 | 1 | 2 | 213 | | xml | 1 | 2 |
| 3 | 1 | 3 | 213 | | xml | 1 | 3 |
| 4 | 2 | 1 | 213 | | xml | 2 | 1 |
| 5 | 2 | 2 | 213 | | xml | 2 | 2 |
| 6 | 2 | 3 | 213 | | xml | 2 | 3 |
| 7 | 4 | 1 | 214 | | xml | 4 | 1 |
------------------------ -----------------------
Now i want to write a query that will select all sID and qID from table A against 213 value and pass those sID and fID to table B and get all text one by one as in below output.
--------------------------
| Text | sID | qID | fID |
--------------------------
| abc | 1 | 1 | 213 |
| abc | 1 | 2 | 213 |
| abc | 1 | 3 | 213 |
| abc | 2 | 1 | 213 |
| abc | 2 | 2 | 213 |
| abc | 2 | 3 | 213 |
--------------------------
I tried the below code.
SELECT s.territoryID, t.name, s.sectionName, s.attributeName, s.shopID, s.attributeID
FROM scoreanalysis AS s
INNER JOIN territories AS t ON s.territoryID = t.ID
WHERE s.territoryID IN
(
SELECT t.ID FROM territories as t
WHERE t.formatID = 213 and t.territorylevelID =349537
and t.lft > 2 and t.rht < 397
)
AND s.achievedScore =0 AND s.applicableScore !=0
AND
SELECT questionComment from comments where
shopID=".$row["shopID"]." and questionID=".$row["attributeID"]
what are possible solution to solve this problem! Any Help? Thanks in Advance
You can join the two tables together, and add the following conditions:
sID matches
qID matches
tableA.fID is 213
In your select, you can pull the text, sid, and qid values from tableB, and the fid from tableA like this:
SELECT b.xmlText, b.sid, b.qid, a.fid
FROM tableA a
JOIN tableB b ON b.sid = a.sid AND b.qid = a.qid AND a.fid = 213;
The exists operator should do the trick:
SELECT `text`
FROM b
WHERE EXISTS (SELECT *
FROM a
WHERE a.sID = b.sID and a.qID = b.qID AND fID = 213)
Try this:
SELECT b.text, a.sid, a.qid, a.fid
FROM a
LEFT OUTER JOIN b ON a.sID = b.sID AND a.qID = b.qID
WHERE a.fID = 213;
SELECT b.xmlText as Text, a.sID, a.qID, a.fID
FROM a, b
WHERE a.sID = b.sID and a.qID = b.qID AND a.fID = 213;
This will give you output as
--------------------------
| Text | sID | qID | fID |
--------------------------
| xml | 1 | 1 | 213 |
| xml | 1 | 2 | 213 |
| xml | 1 | 3 | 213 |
| xml | 2 | 1 | 213 |
| xml | 2 | 2 | 213 |
| xml | 2 | 3 | 213 |
--------------------------
SQL query:
SELECT `qID`,`sID`, `xmlText` AS `text`
FROM `B`
WHERE EXISTS (
SELECT `sID`, `qID`, `fID` , `id`
FROM `a`
WHERE a.sID = B.sID
AND a.qID=B.qID
AND fID=213
)
I have the following 2 tables
tableA a (id, name, surname, program, date)
tableB b (id, aid, name, surname, extracard)
with tableA.id = tableB.aid (1 to n relationship)
Sample data for tableA:
| ID | NAME | SURNAME | PROGRAM | DATE | EXPIRES |
----------------------------------------------------------
| 1 | TOM | JONES | 1,2,3 | 12/8/2012 | 12/8/2013 |
| 2 | JAMIE | OLIVER | 4,5,6 | 15/8/2012 | 15/8/2013 |
Sample data for tableB:
| ID | AID | NAME | SURNAME | CARD |
-------------------------------------
| 1 | 1 | ANNE | JONES | 1 |
| 2 | 1 | JACK | BOWER | 0 |
| 3 | 2 | KATE | PERRY | 1 |
| 4 | 2 | JOHN | DOE | 0 |
| 5 | 2 | HARRY | POTTER | 0 |
In the results, each member of tableB should have all values (program, date, expires, etc...) from tableA and display only the name, surname from tableB in the same column (coalesce??). Also, I need to use a between clause for a.id between (%id1 and %id2) and also a WHERE statement for selecting rows where tableB.card=1
| a.ID | NAME | SURNAME | PROGRAM | DATE | EXPIRES |
------------------------------------------------------------
| 1 | TOM | JONES | 1,2,3 | 12/8/2012 | 12/8/2013 |
| 1 | ANNE | JONES | 1,2,3 | 12/8/2012 | 12/8/2013 |
| 2 | JAMIE | OLIVER | 4,5,6 | 15/8/2012 | 15/8/2013 |
| 2 | KATE | PERRY | 4,5,6 | 15/8/2012 | 15/8/2013 |
SELECT * FROM
( (SELECT a.id ,a.name,a.surname,a.program,a.date,a.expires
from tableA a left outer join tableB b
on b.aid=a.id
where b.card=1 and (a.id between '1' and '2'))
UNION ALL
(SELECT a.id ,b.name,b.surname,a.program,a.date,a.expires
from tableA a left outer join tableB b
on b.aid=a.id
where b.card=1 and (a.id between '1' and '2'))) t
ORDER BY id
EDITED:
Please refer to http://sqlfiddle.com/#!2/d8227/1
Are you looking for -
(SELECT a.id, name, surname, program, date, expires FROM tableA a WHERE a.id BETWEEN '%id1' and '%id2')
UNION
(SELECT a.id, b.name, b.surname, program, date, expires FROM tableB b LEFT JOIN tableA a ON b.aid=a.id WHERE b.card=1 AND (a.id between '%id1' and '%id2') )
ORDER BY a.id ASC
(select a.ID,a.NAME,a.SURNAME,a.PROGRAM,a.DATE,a.EXPIRES from tableA a where ...)
Union All
(select a2.ID,b.NAME,b.SURNAME,a2.PROGRAM,a2.DATE,a2.EXPIRES from tableB b
left join tableA a2 on b.aid = a2.id where ...);
You can choose left/inner join as per your need and where condition too with between clause like.. where id between 2 and 8 or where id > 2 and id < 8.