Transposing rows to columns in MsAccess query - sql

I have a table with
cID, side, row, column
with some data of
24, 1, 10, 5
25, 1, 12, 6
24, 2, 18, 3
and so on. Now I want these data to be show in the form of:
cID=24
side 1 2
row 10 18
column 5 3
cID=25
side 2
row 12
column 6
The cID is filtered in the query so the output will be the 3 rows (side, row, column) and the data of them of a specific cID.
Is that possible with MsAccess Query/SQL and how?
Thanks!

Something on these lines:
TRANSFORM First(q.rvalue) AS firstofrow
SELECT q.rhead
FROM (SELECT cid,
side,
row AS rvalue,
"row" AS rhead
FROM atable
UNION ALL
SELECT cid,
side,
column AS rvalue,
"column" AS rhead
FROM atable) AS q
WHERE q.cid = 24
GROUP BY q.rhead
PIVOT q.side;

Related

How to obtain a uniform sample from my SQL table?

Say I have a simple table:
id, value
2, 5
4, 3
10, 4
20, 5
24, 4
40, 3
60, 3
80, 3
150, 3
90, 3
120, 3
As you can see the majority of the value column is 3. If I want to obtain a subset of this table, there is a high likelihood that 3 would dominate, i.e., SELECT * FROM TABLE LIMIT 10. So how can I thus perform some statistics to ensure that I have a uniform distribution, i.e., a subset that contains 2 of each distinct value?
You can use a query like this
WITH cte AS (
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY value ORDER BY id) AS rn
FROM data
)
SELECT
id,
value
FROM cte
WHERE rn < 3
GROUP BY value, id
It would give you at most 2 rows per value.
You can check a working demo here

Filter coming result in same column

Pointid
Productid
5
24
6
24
6
25
6
26
7
24
7
25
7
26
7
27
For the query:
select distinct pointid
from mytable
where productid in (24,25,26)
The result is: 5,6,7
But I want only 6.
No more No less..
How can I do it?
The main goal is to find those pointid where their productid are EXACTLY 24, 25, 26. Importantly: no more, no less.
In essence, you are requiring two distinct conditions:
That the pointid contains ALL of the following productids; 24, 25, 26, and,
That the pointid does not contain any other productid.
Both conditions can be addressed with a having clause.
You make sure that it contains all of the productids. As there are 3, you want the count of the productids that match 24, 25, 26, to be exactly 3: COUNT(DISTINCT CASE WHEN productid in (24, 25, 26) THEN productid END) = 3.
You want it to contain no other productid. So you make sure that the total value of distinct productids is 3: COUNT(DISTINCT productid) = 3.
The following query puts it all together:
SELECT pointid
FROM mytable
GROUP BY pointid
HAVING COUNT(DISTINCT CASE WHEN productid in (24, 25, 26) THEN productid END) = 3
AND COUNT(DISTINCT productid) = 3
;
If you wanted to do something similar with different conditions (as you mentioned in your comments):
Replace 24,25,26, for the productids that you want to check.
Replace 3 for the number of productids that you are checking.
Use aggregation and having:
select pointid
from mytable
group by pointid
having sum(case when productid in (24, 25, 26) then 1 else 0 end) = 3 and
count(*) = 3;
Here is a db<>fiddle.
If you want to filter the rows where productid is in(24,25,26) and pointid count is maximum. Then try this
SELECT pointid FROM mytable
GROUP BY pointid HAVING productid in(24,25,26)
ORDER BY COUNT(pointid) DESC LIMIT 1;

Why am I having so many records after a join?

I'm trying to join two tables; one reporting information on media campaigns and another on TV spots... Because the second table does not contain any information on campaigns, and because I don't really need it now, I'm joining the two tables based on the id of the TV spot (here, "creative_id") as well as date.
The problem is, there are approx. 6.7 million records in the first table, so I don't understand why, when I run this, I get more than 17 million... :( Can you help, please?
alter view halo2 as
select
h.date,h.channel,h.strategy,h.creative_id,h.programme,h.sub_programme,h.l_c_b,
h.media_plan_split,h.pu,h.conversion_type,h.conversion_new_or_upgrade,
case when h.conversion_new_or_upgrade like '%new%' then 1 else 0 end #acquisitions,
case when h.conversion_new_or_upgrade like '%upg%' then 1 else 0 end #upgrades,
case when h.conversion_contract_length like '%12%' then 12
when h.conversion_contract_length like '%24%' then 24
when h.conversion_contract_length like '%30%' then 1
else 0 end contract_length_in_months,
h.conversion_device_manufacturer,
h.conversion_device,
h.media_spend,
h.#halo,
ft.u10/100 as upfront_cost,
(ft.sales_value+cast(ft.u28 as float))/100 as monthly_cost
from halo h left join in_ft_conversion ft
on h.creative_id=ft.creative_id
and
h.date=ft.sales_date
Here are two tables:
TableA
Number, Text
----
1, Hello
1, There
1, World
TableB
Number, Text
----
1, Foo
1, Bar
1, Baz
Here is a query that joins them:
SELECT * FROM TableA a INNER JOIN TableB b ON a.Number = b.Number
Here are the results:
a.Number, a.Text, b.Number, b.Text
----------------------------------
1, Hello, 1, Foo
1, Hello, 1, Bar
1, Hello, 1, Baz
1, There, 1, Foo
1, There, 1, Bar
1, There, 1, Baz
1, World, 1, Foo
1, World, 1, Bar
1, World, 1, Baz
This is called a Cartesian product; there isn't a 1:1 or even a 1:Many mapping between A and B, there is a Many:Many mapping. Each row in A maps to each row in B, the result that we started out with 3 rows in A, 3 rows in B, if they'd been 1:1 we'd have a 3 row resultset, but because each of 3 rows match up to another 3 rows, we got a 9 row result (3 * 3).
Any time that one of your tables has rows that match to more than one row of another table, as according to your join condition, your resulting row count will increase/multiply
The most common situation is you have more than one record in the joined table that satisfies the join condition(Predicate). If your predicate is not unique on the second table records will repeat on left join.

SQL query to select equal or less than or greater than

Assuming that there is a table t with the following columns: Code int, Name nvarchar(50).
I'd would like to query the table for the most matching row for a given Code c. The 'most matching' criteria (in order of importance):
1) select a row whose Code matches c
2) select a row whose Code is greater than c (but the very first one). For example, if c = 4 and t
contains 1, 2, 3, 5, 6, and 7, I'd like to select 5.
3) select a row whose
Code is less than c. For example, if c = 4 and t contains 3, 2, and
1, I'd like to select 3.
The code is going to be in a stored procedure.
Could someone please suggest how to accomplish the above.
Thanks.
Sample data and expected results:
1, "Name1"
2, "Name2"
4, "Name4"
5, "Name5"
If c=2, result: 2,"Name2"
If c=3, result: 4,"Name4"
if c=6, result: 5,"Name5"
I'd order the rows by two criteria - the absolute distance from the target number and whether it's greater or lesser than it, and just pick the top row. E.g., assuming the target code is 4:
SELECT TOP 1 *
FROM t
ORDER BY ABS(code - 4) ASC, CASE WHEN code > 4 THEN 1 ELSE 0 END DESC
That is a top 1 query; you want the one best matching record. So select TOP 1 along the desired order in ORDER BY.
select top 1 *
from mytable
order by
case when code = #code then 1
when code > #code then 2
else 3
end,
abs(code - #code);

columns to rows change in oracle sql

I have columns a,b in table x.And i want to change this columns data into rows.
it is possible to have duplicate vales in table but in columns to row change only distinct values should come.
E.G:
a b
1 2
1 11
3 4
5 6
7 8
9 10
......etc
the result 1 (query 1) should be 1-2,1-11,3-4,5-6,7-8,9-10.....etc
The result 2 (query 2) should b 1,3,5,7,9....etc(only one 1 must come as we have duplicate data for column a)
how can i achieve this in oracle SQL.
Please help.
For Oracle 11 use function listagg() and in first query concatenate columns, in second - select distinct values at first.
Query 1:
select listagg(a||'-'||b, ',') within group (order by a, b) result from t
RESULT
------------------------------
1-2,1-11,3-4,5-6,7-8,9-10
Query 2:
select listagg(a, ',') within group (order by a) result
from (select distinct a from t)
RESULT
------------------------------
1,3,5,7,9
For older versions you can use wmsys.wm_concat.