I'm a bit rusty on my SQL and Access so just wanted some help.
I have a set of data like the below in Access
C1 C2 C3
1 A C
2 B D
3 B E
From this data I wanted run a SQL query that will combine columns 2 and 3 but also retain the information in column 1 alongside it. I've illustrated this below
C1 C2
1 A
2 B
3 B
1 C
2 D
3 E
I've run a sql query using a union syntax to combine columns 1 and 2 already but can't figure out how to include the column 1 data as well.
Any help on this would be greatly appreciated.
Thanks,
Shan
Don't know access but if it supports union something like:
select c1, c2 as c2 from T
union all
select c1, c3 as c2 from T
should work. If c2 and c3 always differ, or if you are not interested in duplicates union can be used instead of union all
Related
I'm a data analyst, so I write SQL queries to retrieve data from a database. I'm not sure what kind of SQL exactly, just assume the most standard (also not things like 'DECLARE #tbl', and no create functions etc.)
Here is my problem.
Given the following table:
name
number
letter
A
1
a
A
2
b
A
3
c
A
4
d
B
1
a
B
2
b
B
3
c
B
4
d
I want the following result: (concatenate letter cumulatively, order by number))
name
number
letter
result
A
1
a
a
A
2
b
a,b
A
3
c
a,b,c
A
4
d
a,b,c,d
B
1
a
a
B
2
b
a,b
B
3
c
a,b,c
B
4
d
a,b,c,d
Any help is highly appreciated. Thanks very much.
This answers the original version of the question which was tagged MySQL.
MySQL doesn't support group_concat() as a window function. So a subquery may be your best alternative:
select t.*,
(select group_concat(t2.letter order by t2.number)
from t t2
where t2.name = t.name and t2.number <= t.number
) as letters
from t;
How can I merge data into one column for different account numbers. Currently, it looks like this.
TableA.Order TableA.Question TableB.Response
1 a Null
1 b James
1 c Null
2 d Zebra
2 T Null
However, I want it to merge like below:
TableA.Order NewColumn
1 a
1 b
1 c
1 James
2 d
2 T
2 Zebra
Base from my understanding of your question. I devised a solution which answers to it. See my query below:
SELECT * FROM TableA
UNION ALL
SELECT B.Order1,A.Response From
(
(SELECT ROW_NUMBER()OVER(ORDER BY Response)PK,* FROM TableB) A Left Join
(SELECT ROW_NUMBER()OVER(ORDER BY Order1)PK,* FROM TableA) B On A.PK=B.PK
)
Where Response IS NOT NULL
Here what I am trying to do is to get the values for P1,P2,P3 that should comes from A3,
this works well for two tables but not for three...
SELECT x.A1,x.A3,x.A4,A5,A6, x.A2 as P1,y.A2 as P2,z.A2 as P3
FROM Contact x,Contact y,Contact z
WHERE (x.id = y.id) AND (y.id = z.id) AND
(x.A3 ='pre-sale') AND (y.A3= pos-sale') AND(z.A3='current-sale')
ORDER by x.A4 DESC
For example
the CONTACT table will look like this with some expected results for P1,P2, P3
A1 A2 A3 A4 A5 A6 P1 P2 P3
----------------------------------------------------
1 22 pre-sale 9 kk 8 22 31 2
2 31 pos-sale 4 yy 6 44 61 11
3 2 current-sale 1 hh 2 null null null
4 44 pre-sale 2 kk 8
5 61 pos-sale 1 yy 6
6 11 current-sale 1 hh 2
For P1, P2 using twice same table works well, adding the third table the values
for P1, P2 are the same and for P3 all null
I suspect that what you are trying to do might best be done with conditional aggregation. It is a bit hard to tell what you are really trying to accomplish, because not all the columns are aliased. Here is an example
SELECT c.id,
max(case when c.A3 = 'pre-sale' then A4 end) as PreSale_A4,
max(case when c.A3 = 'pos-sale' then A2 end) as PosSale_A2,
max(case when c.A3 = 'current-sale' then A4 end) as CurrentSale_A2
FROM Contact c
group by c.id
order by PreSale_A4 desc;
Your original query has some fundamental problems. For instance, you are using implicit joins via the where clause, which are always inner joins. The solution to your problem might be using outer joins instead. Conditional aggregation probably solves the problem, though.
Below is the sample data:
c1 c2 c3 c4 c5
1 a1 a 1 1
2 a2 a 2 1
3 a3 a 3 1
4 a4 a 4 1
5 b1 b 1 1
6 b2 b 2 1
7 b3 b 3 1
8 b4 b 4 1
9 a1 c 3 1
I want to get the the below details:
c1 c2 c3 c4 c5
1 a1 a 1 1
5 b1 b 1 1
9 a1 c 3 1
C1 is primary key, the criteria is for any given unique(c2) where c4 is the lowest, I want to return the contents(all the 5 columns) of the row.
Try this:
SELECT t1.*
FROM Table1 t1
INNER JOIN
(
SELECT c3, MIN(c4) c4
FROM Table1
GROUP BY c3
) t2 ON t1.c3 = t2.c3 ANd t1.c4 = t2.c4
SQL Fiddle Demo
Update:1 In SQL the returned results is a set set(unless you specify an ORDER BY clause, it is a cursor in this case), wherein the order is not guaranteed. This is a standard. You should use an ORDER BY clause if you want to guarantee a specific order. In your case , the results is not guaranteed to be ordered like 1 5 9. Add ORDER BY c1 instead.
The ORDER BY clause might be crucial in some cases, for example, if want to get the top three rows, or the maximum one, in this case you have to specify an ORDER BY clause.
So if you wants to persist a specific order the you have specify an ORDER BY.
1 As noted by #Fahim Parker, see the comments below.
select c1,c2,c3,c4,c5
from table
where c4= (select min(c4) from table as f where f.c4 = table.c4);
i hope that helps
I have a table with 3 columns in which one is empty.
its like this,
c1 c2 c3
1 1000
1 1001
1 1004
2 1005
2 1007
3 1009
I want to insert values to c3 like
c1 c2 c3
1 1000 1
1 1001 2
1 1004 3
2 1005 1
2 1007 2
3 1009 1
Can anybody help?
The simplest solution is the one that pilcrow describes above: for each record R, c3 is equal to the number of records that have the same c1 as R, and a c2 that is less than or equal to that of R. As a SQL statement:
UPDATE table_name t
SET c3 =
( SELECT COUNT(1)
FROM table_name
WHERE c1 = t.c1
AND c2 <= t.c2
)
;
(Replace table_name with your table-name, of course.)
This might be faster than the nested sub-select (but you will need to test it)
merge into your_table u
using
(
select c1,
c2,
row_number() over (partition by c1 order by c2) as rn
from your_table
) t on (t.c1 = u.c1 and t.c2 = u.c2)
when matched then
update
set u.c3 = rn;