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
)
Related
Sorry for the vague title, but I don't know how to word this type of problem better. Here is a simple example to explain it. I have to tables: OrderItemList and OrderHistoryLog.
OrderItemList:
|------------------------------|
| OrderNo | ItemNo | Loc | Qty |
|------------------------------|
| 100 | A | 1 | 1 |
| 101 | A | 1 | 2 |
| 102 | A | 1 | 1 |
| 103 | A | 2 | 1 |
| 104 | A | 2 | 1 |
OrderHistoryLog:
|------------------------------|
| OrderNo | ItemNo | Loc | Qty |
|------------------------------|
| 50 | A | 1 | 5 |
| 51 | A | 1 | 2 |
| 100 | A | 1 | 1 |
| 102 | A | 1 | 3 |
| 103 | A | 2 | 1 |
I need to show the records in the OrderItemList along with a LocHistQty field, which is the sum(Qty) from the OrderHistoryLog table for a given Item and Location, but only for the orders that are present in the OrderItemList.
For the above example, the result should be:
Result:
|------------------------------------------------------
| OrderNo | ItemNo | Loc | Qty | HistQty | LocHistQty |
|------------------------------|-----------------------
| 100 | A | 1 | 1 | 1 | 4 |
| 101 | A | 1 | 2 | 0 | 4 |
| 102 | A | 1 | 1 | 3 | 4 |
| 103 | A | 2 | 1 | 1 | 1 |
| 104 | A | 2 | 1 | 0 | 1 |
It is the last field, LocHistQty that I could use some help with. Here is what I started with (does not work):
select OI.OrderNo, OI.ItemNo, OI.Loc, OI.Qty, IFNULL(OL.Qty, 0) as HistQty, OL2.LocHistQty
from OrderItemList OI
left join OrderItemLog OL on OL.OrderNo = OI.OrderNo and OL.ItemNo = OI.ItemNo
join
(
select ItemNo, Loc, sum(qty) as LocHistQty
from zOrderItemLog
group by ItemNo, Loc
) as OL2
on OL2.ItemNo = OI.ItemNo and OL2.Loc = OI.Loc
order by OrderNo
The issue is with the above SQL is that LocHistQty contains the summary of the Qty for all orders (=11 for Loc 1 and 1 for Loc 2), not only the ones in OrderItemList.
Lastly, the real data is voluminous and query performance is important.
Help would be much appreciated.
The subquery can join with OrderItemList to restrict the order numbers that it sums.
select OI.OrderNo, OI.ItemNo, OI.Loc, OI.Qty, IFNULL(OL.Qty, 0) as HistQty, OL2.LocHistQty
from OrderItemList OI
left join OrderItemLog OL on OL.OrderNo = OI.OrderNo and OL.ItemNo = OI.ItemNo
join
(
select OL.ItemNo, OL.Loc, sum(OL.qty) as LocHistQty
from OrderItemLog AS OL
JOIN OrderItemList AS OI ON OL.OrderNo = OI.OrderNo
group by OL.ItemNo, OL.Loc
) as OL2
on OL2.ItemNo = OI.ItemNo and OL2.Loc = OI.Loc
order by OrderNo
DEMO
Option 1
SELECT
OrderNo,
ItemNo,
Loc,
Qty,
(SELECT
Qty
FROM
OrderHistoryLog AS A
WHERE
A.OrderNo = B.OrderNo AND A.Loc = B.Loc) AS HistQty,
(SELECT
SUM(Qty)
FROM
OrderHistoryLog AS D
WHERE
D.OrderNo = B.OrderNo AND D.Loc = B.Loc) AS LocHistQty
FROM
OrderItemList AS B;
Option 2
SELECT
B.OrderNo,
B.ItemNo,
B.Loc,
B.Qty,
C.Qty AS HistQty,
(SELECT
SUM(Qty)
FROM
OrderHistoryLog AS A
WHERE
A.OrderNo = B.OrderNo AND A.Loc = B.Loc) AS LocHistQty
FROM
OrderItemList AS B,
OrderHistoryLog AS C
WHERE
C.OrderNo = B.OrderNo AND C.Loc = B.Loc;
I have two tables
table song
| ID | TITLE | AUTOR | CODE |
| 1 | title_1 | autor_1 | 123 |
| 2 | title_2 | autor_2 | 1332 |
| 3 | title_3 | autor_3 | 3434 |
table playlist
| ID | DATE | EVENT |
| 1 | 2020-05-01 | 123 |
| 2 | 2020-05-02 | 3434 |
| 3 | 2020-09-23 | 123 |
now I create a VIEW because table are very large
CREATE OR REPLACE VIEW View_song
AS
select c.id, c.title, c.autor, c.code,
( select
count(p.event) from playlist p
where p.event = c.code
) as total_counter
from song c
So I have a VIEW with the total songs + the column total_counter
| ID | TITLE | AUTOR | CODE | total_counter |
| 1 | title_1 | autor_1 | 123 | 2 |
| 2 | title_2 | autor_2 | 1332 | 0 |
| 3 | title_3 | autor_3 | 3434 | 0 |
I want to add a column to the VIEW so I want to have a more column with today_counter
| ID | TITLE | AUTOR | CODE | total_counter | today_counter |
| 1 | title_1 | autor_1 | 123 | 2 | 0 |
| 2 | title_2 | autor_2 | 1332 | 0 | 0 |
| 3 | title_3 | autor_3 | 3434 | 0 | 1 |
I try this query
CREATE OR REPLACE VIEW View_song
AS
select c.id, c.title, c.autor, c.code,
( select
count(p.event) from playlist p
where p.event = c.code
) as total_counter
( select
count(p.event) from playlist p
where p.event = c.code AND date = CURDATE()
) as today_counter
from song c
but it doesn't work
Use GROUP BY to these calculations in single go.
CREATE OR REPLACE VIEW View_song
AS
SELECT
c.id, c.title, c.author, c.code,
COUNT(p.`event`) AS total_counter,
SUM(IF(p.`date` = CURDATE(), 1, 0)) AS today_counter
FROM song c
LEFT JOIN playlist p ON c.`code` = p.`event`
GROUP BY c.id;
Add index on date, code and event to make it faster.
Also in your query, you're missing comma after total_counter.
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
How to select all addons which a specific user has not buyed or are no longer valid?
Assuming currentdate is 2017-03-02 17:00:00
Table1 (users):
+-----------+----------+
| id | username |
+-----------+----------+
| 1 | Walter |
| 2 | Hank |
| 3 | John |
+-----------+----------+
Table2 (buyLog):
+-----------+----------+------------+---------------------+
| id | idUsers | idItems | validUntil |
+-----------+----------+------------+---------------------+
| 1 | 1 | 1 | 2016-03-02 14:15:47 |
| 2 | 1 | 1 | 2018-03-02 14:15:47 |
| 3 | 1 | 2 | 2016-03-02 14:15:47 |
| 4 | 2 | 1 | 2018-03-02 14:15:47 |
+-----------+----------+------------+---------------------+
Table3 (addons):
+-----------+----------+
| id | name |
+-----------+----------+
| 1 | Foo |
| 2 | Bar |
| 3 | Lorem |
+-----------+----------+
Expected output for user with id 1 should be:
+-----------+----------+
| id | name |
+-----------+----------+
| 2 | Bar |
| 3 | Lorem |
+-----------+----------+
See SQL Fiddle here: http://sqlfiddle.com/#!9/16356
Where I have the most problems is to handle the validUntil in the leftJoin.
I think I have to group by during the left join to tread only the most recent validUntil record. Maybe using max(validUntil)?
This code will work
http://sqlfiddle.com/#!9/16356/1/0
SELECT
C.ID AS 'ID',
C.NAME AS 'NAME'
FROM
(SELECT
A.id AS 'ID',A.name AS 'NAME',
CASE
WHEN B.YY > '2017-03-02 17:00:00' THEN 0
ELSE 1 END AS 'Tag'
FROM
addons AS A
LEFT JOIN
(SELECT idItems AS 'XX', MAX(validUntil) AS 'YY'
FROM
buyLog
WHERE idUsers = 1 GROUP BY 1) AS B
ON
A.id = B.XX) AS C
WHERE
C.Tag = 1
My sense is that neither your explanation nor your data set and desired result are adequate to the task of explaining the problem. The following query produces the desired result, but perhaps that's just coincidence...
SELECT a.*
FROM addons a
LEFT
JOIN buylog b
ON b.iditems = a.id
AND b.validuntil > NOW()
LEFT
JOIN users u
ON u.id = b.idusers
AND u.id = 1
WHERE b.validuntil IS NULL
AND u.id IS NULL;
Hi I have doubt in sql server
dept
+---------+--------+
| deptkey | deptno |
+---------+--------+
| 1 | 100 |
| 2 | 101 |
| 3 | -1 |
+---------+--------+
loc
+--------+-------+
| lockey | locid |
+--------+-------+
| 1 | 200 |
| 2 | 201 |
| 3 | -1 |
+--------+-------+
trans
+----+--------+-------+------+
| id | deptno | locid | Name |
+----+--------+-------+------+
| 1 | 100 | 201 | abc |
| 2 | 101 | 203 | def |
| 3 | 103 | 200 | rav |
| 4 | 105 | 204 | jai |
| 1 | 101 | 200 | kal |
| 4 | 100 | 206 | lo |
+----+--------+-------+------+
here tran deptno= dept.deptno then corresponding key values bring if not match then we need to unmatched deptno assign -1 and corresponding key need to retrive
similar tran locid=loc.locid
based on above tables I want output like below
+----+------+---------+--------+
| id | Name | deptkey | lockey |
+----+------+---------+--------+
| 1 | abc | 1 | 2 |
| 2 | def | 2 | 3 |
| 3 | rav | 3 | 1 |
| 4 | jai | 3 | 3 |
| 1 | kal | 2 | 1 |
| 4 | lo | 1 | 3 |
+----+------+---------+--------+
I tried like below query
SELECT a.[id],a.name ,b.deptkey,c.lockey
FROM [trans] a left join dept b on a.deptno=b.deptno
left join loc c on a.locid=c.locid
above query not given expected result can you please tell me how to write query to achive this task in sql server
SELECT a.[id],a.name ,
(CASE WHEN b.deptkey IS NULL THEN (select deptkey from DEPT WHERE DeptNo = -1)
ELSE b.deptkey END) AS 'deptkey',
(CASE WHEN c.lockey IS NULL THEN (select LocKey from LOC WHERE LocId = -1)
ELSE c.lockey END) AS 'lockey '
FROM [trans] a left join dept b on a.deptno=b.deptno
left join loc c on a.locid=c.locid
http://www.sqlfiddle.com/#!3/389463/2
SELECT a.[id],a.name ,b.deptkey,c.lockey
FROM [trans] a left join dept b on isnull(a.deptno,-1)=isnull(b.deptno,-1)
left join loc c on a.locid=c.locid
try with this...
SELECT
a.[id]
, a.name
, ISNULL(b.deptkey,-1) AS [deptkey]
, ISNULL(b.lockey,-1) AS [lockey]
FROM [trans] a
left join dept b
on a.deptno = b.deptno
left join loc c
on a.locid = c.locid
When the value is not found ISNULL, change the result to -1 instead of NULL. You can just change the -1 with any default value you prefer as unmatched.
OR if you want a query driven default value (get the last record as the default value). You can change your script as presented below.
SELECT
a.[id]
, a.name
, ISNULL(b.deptkey,(SELECT TOP 1 deptno from dept ORDER BY deptkey DESC)) AS [deptkey]
, ISNULL(b.lockey,(SELECT TOP 1 locid from loc ORDER BY lockey DESC)) AS [lockey]
FROM [trans] a
left join dept b
on a.deptno = b.deptno
left join loc c
on a.locid = c.locid