I have a table of preferences, called "txp_prefs". I would like to return multiple preferences into a single row; the reason I prefer this to a simple concatenation is that I'm using a plugin in textpattern which can process the single row.
Here is the testing data I have:
------------------------------------------------
|Id | event | name |value |
------------------------------------------------
| 1 | season | season_start | 12/10/2011 |
-----------------------------------------------
| 2 | season | season_end | 29/10/2011 |
------------------------------------------------
| 3 | season | season_countdown | 7 |
------------------------------------------------
| 4 | another | test1 | result1 |
------------------------------------------------
| 3 | | test2 | result2 |
------------------------------------------------
The final result I would like to get is:
----------------------------------------------------------
|event | season_start | season_end | season_countdown |
----------------------------------------------------------
|season | 12/10/2011 | 29/10/2011 | 7 |
----------------------------------------------------------
I can (obviously) create the separate queries to get each result independently; for example
SELECT t1.event, t1.val AS season_start FROM txp_prefs t1 WHERE t1.event="season" AND t1.name="season_start" (to get the season_start)
SELECT t2.event, t2.val AS season_end FROM txp_prefs t2 WHERE t2.event="season" AND t2.name="season_end" (to get the season_end)
But I get errors when I try to join the two together, eg like this:
SELECT t1.event, t1.val AS season_start FROM txp_prefs t1 WHERE t1.event="season" AND t1.name="season_start"
LEFT JOIN
(SELECT t2.event, t2.val AS season_end FROM txp_prefs t2 WHERE t2.event="season" AND t2.name="season_end") t3
ON t1.event=t3.event
The error messages says it is something to do with the join (which I guessed anyway - the two individual queries work.
Any ideas? I have recently figured through joining different tables together, so I assume it is possible to join a table to itself.
Based on the structure given you can use
SELECT
MAX(CASE WHEN name = 'season_start' THEN value END) AS season_start,
MAX(CASE WHEN name = 'season_end' THEN value END) AS season_end,
MAX(CASE WHEN name = 'season_countdown' THEN value END) AS season_countdown
FROM txp_prefs
WHERE event='season'
You can do this by pivoiting. Asper my past project I demostrate you in following query hope will be useful to you.
My table transaction is having following fields
NAME VARCHAR2(10)
branch_code NUMBER(4)
Ruppes NUMBER(4)
SQL> select * from transaction;
NAME branch_code Ruppes
---------- ---------- ----------
Hemang 2602 1000
Hemang 2603 2000
Hemang 2400 3000
Yash 2602 1500
Yash 2603 1200
Yash 2400 1340
Krupesh 2602 1250
Krupesh 2603 2323
Krupesh 2400 8700
9 rows selected.
Now pivoting.
SQL> select branch_code,
2 max( decode( name, 'Hemang', Ruppes, null ) ) "Hemang",
3 max( decode( name, 'Yash', Ruppes, null ) ) "Yash",
4 max( decode( name, 'Krupesh', Ruppes, null ) ) "Krupesh"
5 from
6 (
7 select name, branch_code, Ruppes
8 from transaction
9 )
10 group by branch_code ;
branch_code Hemang Yash Krupesh
---------- ---------- ---------- ----------
2602 1000 1500 1250
2603 2000 1200 2323
2400 3000 1340 8700
select you are looking for is:
SELECT distinct
t0.event,
t1.val AS season_start ,
t2.val as seasson_end,
t3.val as season_countdown
FROM
txp_prefs t0
left outer join
txp_prefs t1
on ( t1.event=t0.event AND t1.name="season_start" )
left outer join
txp_prefs t2
on ( t2.event=t0.event AND t2.name="season_end" )
left outer join
txp_prefs t3
on ( t3.event=t0.event AND t3.name="season_countdown" )
WHERE
t0.event="season"
(the standard way to get only one row is 'distintc' reserved word. Another solution is append 'LIMIT 1' to query, but this is MySQL dependant)
are you sure that your database is right normalized?
see you.
Related
i have 3 tables :
table1
code(Primary key) | name | quantity
B001 | sand | 50
B002 | nail | 100
B003 | paint | 10
=======
table2
code | qty_out
B001 | 2
B001 | 1
B001 | 20
B002 | 10
B002 | 30
=======
table3
code | qty_in
B001 | 1
B001 | 5
B002 | 5
B002 | 10
=======
Result that I want is:
table1
code | name | quantity | Out | In | total
B001 | sand | 50 | 23 | 6 | 33
B002 | nail | 100 | 40 | 15 | 75
B003 | paint | 10 | null/0 | null/0 | 10
I used this query :
SELECT table1.code, table1.name, table1.quantity, sum(table2.qty_out ) AS 'Out', sum( table3.qty_in ) AS 'In'
FROM table1
LEFT JOIN table2 ON table2.code = table1.code
LEFT JOIN table3 ON table3.code = table1.code
GROUP BY table1.code
ORDER BY table1.code ASC
In that query I get result like this...code B001 out 46 and in 18, code B002 out 80 and in 30, code B003 out null and in null
How to fix this?
use this query
select t.code,t.name,t.quantity,t.out,t.in,(t.out+t.in) as total
from (
SELECT table1.code, table1.name, table1.quantity,
( select sum(table2.qty_out)
from table2
where table1.code=table2.code ) as out,
( select sum(table3.qty_in)
from table3
where table3.code=table1.code ) as in
FROM table1
) as t
Using a subquery, a UNION clause and GROUPping, I built the following query :
SELECT
p.code,
p.name,
-- Using IFNULL to handle products without stock variation
IFNULL(SUM(q.q_in), 0) AS total_in,
IFNULL(SUM(q.q_out), 0) AS total_out,
-- Compute the new stock level
p.qty + IFNULL(SUM(q.q_in), 0) - IFNULL(SUM(q.q_out), 0) AS qty
FROM (
-- UNION (= concatenate) prod_in and prod_out tables
SELECT
product,
qty AS q_in,
0 AS q_out -- Enforce schema (otherwise, q_out is dropped)
FROM prod_in
UNION
SELECT
product,
0 AS q_in,
qty AS q_out
FROM prod_out
) AS q
-- Using a RIGHT join to show products without stock variations
RIGHT JOIN products AS p
ON p.code = q.product
-- Group by id to get the summarized view
GROUP BY q.product
Here's the query in a working SQLfiddle with your sample data
I have a huge table where a new row could be an "adjustment" to a previous row.
TableA:
Id | RefId | TransId |Score
----------------------------------
101 | null | 3001 | 10
102 | null | 3002 | 15
103 | null | 3003 | 15
104 | 101 | | -5
105 | null | 3004 | 5
106 | 105 | | -10
107 | null | 3005 | 15
TableB:
TransId | Person
----------------
3001 | Harry
3002 | Draco
3003 | Sarah
3004 | Ron
3005 | Harry
In the table above, Harry was given 10 points in TableA.Id=101, deducted 5 of those points in TableA.Id=104, and then given another 15 points in TableA.Id=107.
What I want to do here, is return all the rows where Harry is the person connected to the score. The problem is that there is no name attached to a row where points are deducted, only to the rows where scores are given (through TableB). However, scores are always deducted from a previously given score, where the original transaction's Id is referred to in the tables as "RefId".
SELECT
SUM TableA.Score
FROM TableA
LEFT JOIN TableB ON TableA.Trans=TableB.TransId
WHERE 1
AND TableB.Person='Harry'
GROUP BY TableA.Score
That only gives me the points given to Harry, not the deducted ones. I would like to get the total scored returned, which would be 20 for Harry. (10-5+15=20)
How do I get MySQL to include the negative scores as well? I feel like it should be possible using the TableA.RefId. Something like "if there is a RefId, get the score from this row, but look at the corresponding TableA.Id for the rest of the data".
Select sum(total) AS total
From tableb
Join
(
Select t1.transid, sum(score) AS total
From tablea t1
Join tablea t2 on t1.id = t2.refid
group by t1.transid
) x on x.transid = tableb.transid
Where TableB.Person='Harry'
try this:
select sum(sum1 + sums) as sum_all from (
SELECT t1.id,T1.Score sum1, coalesce(T2.score,0) sums
FROM Table1 t1
inner JOIN Table2 ON T1.TransId=Table2.TransId
left JOIN Table1 t2 ON t2.RefId = t1.id
WHERE Table2.Person='Harry'
)c
DEMO HERE
OUTput:
SUM_ALL
20
If you assume that adjustments don't modify adjustments, you can do this without aggregating all the data:
select sum(a.score + coalesce(aref.score, 0)) as HarryScore
from tableA a left outer join
tableA aref
on a.refId = aref.id left outer join
tableB b
on a.TransId = b.Transid left outer join
tableB bref
on aref.TransId = bref.TransId
where b.Person = 'Harry' or bref.Person = 'Harry';
I have a table
--------------------
ID | Name | RollNO
--------------------
1 | A | 18
--------------------
2 | B | 19RMK2
--------------------
3 | C | 20
--------------------
My second table is
-----------------------
OldRollNo | NewRollNo
-----------------------
18 | 18RMK1
-----------------------
19 | 19RMK2
-----------------------
20 | 20RMK3
-----------------------
21 | 21RMK4
-----------------------
22 | 22RMK5
-----------------------
I want the resulting table like
----------------------------------
ID | Name | RollNo | LatestRollNo
----------------------------------
1 | A | 18 | 18RMK1
----------------------------------
2 | B | 19RMK2 | 19RMK2
----------------------------------
3 | C | 20 | 20RMK3
----------------------------------
What would be the select query like? This is just the replica of my problem. I have used CASE Statement with the select query but as the records in my table is large, it's taking too much time. In my second table the OldRollNo Column is unique.One more thing is that in the resultant RollNo column if the newly assigned RollNo is already present then it should be copied exactly to the next column i.e LatestRollNo. I have to check only those RollNo which are old.
Thanks.
Try something like this:
select t1.ID
, t1.Name
, t1.RollNO
, LatestRollNO = coalesce(n.NewRollNo, o.NewRollNo)
from t1
left join t2 o on t1.RollNO = o.OldRollNo
left join t2 n on t1.RollNO = n.NewRollNo
SQL Fiddle with demo.
It sounds like your issue is performance not logic; something like this should hopefully allow approriate index usage assuming you have the appropriate indexes on t2.OldRollNo and t2.NewRollNo.
The problem with OR or CASE in a WHERE clause is that these don't always lend themselves to efficient queries; hopefully this will be a bit more useful in your case.
select f.ID, f.name, f.RollNo, s.NewRollNo as "Latest RollNo"
from FirstTable f
inner join
SecondTable s on f.RollNo = s.OldRollNo or f.RollNo = s.NewRollNo
select t.id,t.name,t.rollno,tt.newrollno as latestrollno from
talble1 t
left join
table2 tt on t.rollno = tt.oldrollno
You need to use inner join.
SELECT t1.ID,t1.Name,t2.RollNo,t2.NewRollNo AS LatestRollNo
FROM Table1 t1
INNER JOIN Table2 t2
ON t1.RollNo=t2.OldRollNo OR t1.RollNo=t2.NewRollNo
I have one table:
id | parent_id | name
1 | NULL | audi
2 | 1 | a5
3 | 1 | a6
4 | NULL | opel
5 | 4 | astra
6 | 4 | vectra
I want get name of record and name of record's parent.
One example is to fetch the name for id=5 and its parent name.
id | name | parent_name
5 | astra | opel
What would be SQL query for this?
My query:
SELECT name, parent_id FROM `cats` WHERE `id` = 5 OR `id` =
cats.parent_id LIMIT 0 , 30
didn't work.
You can use the below query:
SELECT T1.id, T1.name, T2.name as parentname
FROM TABLE1 T1
INNER JOIN TABLE1 T2 ON T1.id = T2.parent_id
WHERE T2.ID = 5
SQL FIDDLE
This work's if you have only 1 parent at a time (no recursion):
SELECT a.name name, b.name parent_name
FROM tablexyz a,tablexyz b where
a.id=5 AND a.parent_id=b.id;
This worked fine for me. Please check it out.
select a.id,a.name,b.name as parent from cats a,cats b where b.id=a.parent_id;
You can add any other conditions too. (make sure to use the correct table identifier; a or b)
I have a table say :
id| AccID | Subject | Date
1 | 103 | Open HOuse 1 | 11/24/2011 9:00:00 AM
2 | 103 | Open HOuse 2 | 11/25/2011 10:00:00 AM
3 | 72 | Open House 3 | 11/26/2011 1:10:28 AM
4 | 82 | OPen House 4 | 11/27/2011 5:00:29 PM
5 | 82 | OPen House 5 | 11/22/2011 5:00:29 PM
From the above table, i need all the unique values for the Accid. But say, if there are two or more columns with the same Accid, then i need the one which has the smaller date (among the columns which have the same Accid)
So, from the above table, the o/p should be :
1
3
5
Can any1 please help me in this ? Thanks
SELECT t1.*
FROM [MyTable] t1
INNER JOIN
(
SELECT AccID, MIN(Date) Date
FROM [MyTable]
GROUP BY AccID
) t2 ON t1.AccID = t2.AccID AND t1.Date = t2.Date
More than just the AccID but...
WITH SEL
AS
(
SELECT AccID, MIN(DATE)
FROM table
GROUP BY AccID
)
SELECT table.*
FROM table
JOIN SEL ON SEL.AccID = table.AccID