Find a laboratory where elements are not repeated POSTGRESQL - sql

I have multiple tables:
create table computer(
id int primary key,
id_monitor int references monitor(id),
laboratory_number int not null
);
create table monitor(
id int primary key,
id_company int references company_monitor(id),
);
create table company_monitor(
id int primary key,
name varchar(10)
);
I want to get the number of a laboratory where all monitor manufacturers are different (don`t repeat). I imagined this implementation as follows: we look for how many times manufacturers repeat and find where they repeat 1 time. But the difficulty is that the total number of repetitions, and i need it in each individual laboratory.
Example:
Table "computer"
id | id_monitor | id_company_cpu | cpu_name | ram | ssd | gpu | laboratory_number
----+------------+----------------+----------------+-----+-----+-------------------------+-------------------
1 | 1 | 1 | Core i5 10800F | 8 | 500 | Nvidia GeForce GTX 1050 | 1
2 | 2 | 2 | Ryzen 5 3600 | 8 | 500 | Radeon RX 580 | 2
3 | 3 | 1 | Core i5 10800F | 8 | 500 | Nvidia GeForce GTX 1050 | 1
4 | 4 | 1 | Core i5 10800F | 8 | 500 | Nvidia GeForce GTX 1050 | 1
5 | 5 | 2 | Ryzen 5 3600 | 8 | 500 | Radeon RX 580 | 2
Table "monitor"
id | id_company | diagonal | id_matrix | display_resolution
----+------------+----------+-----------+--------------------
1 | 3 | 24 | 2 | 1980*1280
2 | 2 | 27 | 1 | 2560*1440
3 | 3 | 24 | 3 | 1980*1280
4 | 3 | 24 | 1 | 1980*1280
5 | 2 | 24 | 3 | 1980*1280
Table "company_monitor"
id | name
----+---------
1 | ASUS
2 | ACER
3 | SAMSUNG
Query result should be like this (result: laboratory number 1, since all monitor manufacturers are different in it, laboratory number 2 has the same):
labalatory_number
-----------------
1
I made this request:
select monitor.id_company, count(*)
from monitor join computer on computer.id_monitor = monitor.id
group by monitor.id_company

check this out
with w as (
select distinct c.laboratory_number, c.id_monitor, m.id_company
from computer c join monitor m on c.id_monitor = m.id
)
select laboratory_number
from w
group by laboratory_number
having count(1) = count(distinct id_company)

Related

How do you use two aggregate functions for separate tables in a join?

Sorry if this is a noob question!
I have two tables - a movie and a comment table.
I am trying to return output of the movie name and each comment for that movie as long as that movie has more than 1 comment associated to it.
Here are my tables
test_movies=# SELECT * FROM movie;
id | name | rating | release_date | original_copy_location
----+------------------------------------+--------+--------------+------------------------
1 | Cruella | 9 | 2021-05-28 | 4
7 | Shutter Island | 9 | 2010-02-19 | 4
9 | Grown Ups | 7 | 2010-06-25 | 4
11 | Guardians of the Galaxy: Volume 1 | 8 | 2014-09-01 | 4
14 | The RIng | 8 | 2002-10-18 | 4
17 | Digimon: The Movie | 6 | 2000-01-10 | 4
19 | Star Wars Episode 1 | 5 | 1999-06-21 | 4
20 | Ghosts Of Mars | 5 | 1998-09-15 | 4
5 | Interstellar | 8 | 2014-11-07 | 1
10 | Mean Girls | 8 | 2004-04-30 | 1
12 | Captain America: The First Avenger | 7 | 2011-07-22 | 1
15 | Get Out | 6 | 2017-02-24 | 1
6 | The Dark Knight | 10 | 2008-07-18 | 2
16 | Pokemon: The First Movie | 5 | 1998-11-10 | 2
18 | The Last Dance | 8 | 2020-05-01 | 2
8 | Just Go With It | 8 | 2011-02-11 | 3
13 | The Blair Witch Project | 8 | 1999-08-29 | 3
(17 rows)
test_movies=# SELECT * FROM comments;
c_id | c_comment | c_movie | c_user
------+--------------------------------------+---------+--------
1 | testing comment 1 | 16 | 4
2 | testing comment 1 | 1 | 1
3 | testing comment 1 | 1 | 2
4 | testing comment 1 | 8 | 5
5 | testing comment 1 | 6 | 3
6 | testing comment 1 | 12 | 2
7 | testing comment 1 | 20 | 3
8 | testing comment 1 | 16 | 5
9 | testing comment 1 | 17 | 4
10 | testing comment 1 | 12 | 2
(10 rows)
Output im trying to get is this:
name | c_comment
------------------------+-------------------------------------
Cruella | testing comment 1
Curella | testing comment 1
Pokemon:The First Movie | testing comment 1
Pokemon:The First Movie | testing comment 1
Captain America | testing comment 1
Captain America | testing comment 1
The problem with my queries is that I can't figure out how to return both the movie name and comment associated with it using aggregate functions.
If I use the count in the first select statement it returns all rows:
SELECT m.name, c.c_comment FROM movie m, comments c WHERE m.id = c.c_movie GROUP BY m.name, c.c_comment HAVING COUNT(m.name) >= 1;
If I try the below subquery I get the error - ERROR: subquery must return only one column
SELECT m.name, c.c_comment FROM movie m, comments c WHERE m.id = c.c_movie AND(SELECT m.name, COUNT(c.c_movie) FROM movie m, comments c WHERE m.id =c.c_movie GROUP BY name HAVING COUNT(c.c_movie) > 1);
Still a bit new to SQL as I'm a student and having a tough time figuring this query out lol.
Thanks in advance!
Something like this could work
select m.name, c.c_comment
from movie m
join comment c
on c.c_movie = m.id
where exists (select 1 from comments cc where cc.c_movie=m.id group by c_movie having count(*)>1)
It's standard sql, but you cannot work with mysql and postgresql at the same time... 🤔
Use window functions!
select m.name, c.c_comment
from movie m join
(select c.*, count(*) over (partition by c_movie) as cnt
from comment c
) c
on c.c_movie = m.id
where cnt > 1;

Simple algebra with recursive SQL

The following schema is used to create simple algebraic formulas. variables is used to create formulas such as x=3+4y. variables_has_sub_variables is used to combine the previous mentioned formulas and uses the sign column (will be +1 or -1 only) to determine whether the formula should be added or subtracted to the combination.
For instance, variables table might have the following data where the Implied Formulas column is not really in the table but just for illustrative purposes only.
variables table
+-----------+-----------+-------+------------------+
| variables | intercept | slope | Implied Formula |
+-----------+-----------+-------+------------------+
| 1 | 2.86 | -0.82 | Y1=+2.86-0.82*X1 |
| 2 | 2.96 | -3.49 | Y2=+2.96-3.49*X2 |
| 3 | 2.56 | 2.81 | Y3=+2.56+2.81*X3 |
| 4 | 3.04 | -3.43 | Y4=+3.04-3.43*X4 |
| 5 | -1.94 | 4.11 | Y5=-1.94+4.11*X5 |
| 6 | -1.21 | -0.62 | Y6=-1.21-0.62*X6 |
| 7 | 0.88 | -0.61 | Y7=+0.88-0.61*X7 |
| 8 | -2.77 | -0.34 | Y8=-2.77-0.34*X8 |
| 9 | 1.81 | 1.65 | Y9=+1.81+1.65*X9 |
+-----------+-----------+-------+------------------+
Then, given the below variables_has_sub_variables data, the variables combined resulting in X7=+Y1-Y2+Y3, X8=+Y4+Y5-Y7, and X9=+Y6-Y7+Y8. Next Y7, Y8, and Y9 can be derived using the variables table resulting in Y7=+0.88-0.61*X7, etc. Note that the application will prevent an endless loop such as inserting a record where variables equals 7 and sub_variables equals 9 as variable 9 is based on variable 7.
variables_has_sub_variables table
+-----------+---------------+------+
| variables | sub_variables | sign |
+-----------+---------------+------+
| 7 | 1 | 1 |
| 7 | 2 | -1 |
| 7 | 3 | 1 |
| 8 | 4 | 1 |
| 8 | 5 | 1 |
| 8 | 7 | -1 |
| 9 | 6 | 1 |
| 9 | 7 | -1 |
| 9 | 8 | 1 |
+-----------+---------------+------+
My objective is given any variable (i.e. 1 to 9), determine the constants and root variables where a root variable is defined as not being in variables_has_sub_variables.variables (I can also easily a root column to variables if needed), and these root variables includes 1 through 6 using my above example data.
Doing so for a root variable is easier as there are no sub_variables and is simply Y1=+2.86-0.82*X1.
Doing so for variable 7 is a little trickier:
Y7=+0.88-0.61*X7
=+0.88-0.61*(+Y1-Y2+Y3)
=+0.88-0.61*(+(+2.86-0.82*X1)-(+2.96-3.49*X2)+( +2.56+2.81*X3))
= -0.62 + 0.50*X1 - 2.13*X2 - 1.71*X3
Now the SQL. Below is how I created the tables:
CREATE DATABASE algebra;
USE algebra;
CREATE TABLE `variables` (
`variables` INT NOT NULL,
`slope` DECIMAL(6,2) NOT NULL DEFAULT 1,
`intercept` DECIMAL(6,2) NOT NULL DEFAULT 0,
PRIMARY KEY (`variables`))
ENGINE = InnoDB;
CREATE TABLE `variables_has_sub_variables` (
`variables` INT NOT NULL,
`sub_variables` INT NOT NULL,
`sign` TINYINT NOT NULL,
PRIMARY KEY (`variables`, `sub_variables`),
INDEX `fk_variables_has_variables_variables1_idx` (`sub_variables` ASC),
INDEX `fk_variables_has_variables_variables_idx` (`variables` ASC),
CONSTRAINT `fk_variables_has_variables_variables`
FOREIGN KEY (`variables`)
REFERENCES `variables` (`variables`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_variables_has_variables_variables1`
FOREIGN KEY (`sub_variables`)
REFERENCES `variables` (`variables`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
INSERT INTO variables(variables,intercept,slope) VALUES (1,2.86,-0.82),(2,2.96,-3.49),(3,2.56,2.81),(4,3.04,-3.43),(5,-1.94,4.11),(6,-1.21,-0.62),(7,0.88,-0.61),(8,-2.77,-0.34),(9,1.81,1.65);
INSERT INTO variables_has_sub_variables(variables,sub_variables,sign) VALUES (7,1,1),(7,2,-1),(7,3,1),(8,4,1),(8,5,1),(8,7,-1),(9,6,1),(9,7,-1),(9,8,1);
And now the queries. XXXX is 7, 8, and 9 for the following results. Before each query, I show my expected results.
WITH RECURSIVE t AS (
SELECT v.variables, v.slope, v.intercept
FROM variables v
WHERE v.variables=XXXX
UNION ALL
SELECT v.variables, vhsv.sign*t.slope*v.slope slope, vhsv.sign*t.slope*v.intercept intercept
FROM t
INNER JOIN variables_has_sub_variables vhsv ON vhsv.variables=t.variables
INNER JOIN variables v ON v.variables=vhsv.sub_variables
)
SELECT variables, SUM(slope) constant FROM t GROUP BY variables
UNION SELECT 'intercept' variables, SUM(intercept) intercept FROM t;
Variable 7 Desired
+-----------+----------+
| variables | constant |
+-----------+----------+
| 1 | 0.50 |
| 2 | -2.13 |
| 3 | -1.71 |
| intercept | -0.6206 |
+-----------+----------+
Variable 7 Actual
+-----------+----------+
| variables | constant |
+-----------+----------+
| 1 | 0.50 |
| 2 | -2.13 |
| 3 | -1.71 |
| 7 | -0.61 |
| intercept | -0.61 |
+-----------+----------+
5 rows in set (0.00 sec)
Variable 8 Desired
+-----------+-----------+
| variables | constant |
+-----------+-----------+
| 1 | 0.17 |
| 2 | -0.72 |
| 3 | -0.58 |
| 4 | 1.17 |
| 5 | -1.40 |
| intercept | -3.355004 |
+-----------+-----------+
Variable 8 Actual
+-----------+----------+
| variables | constant |
+-----------+----------+
| 1 | 0.17 |
| 2 | -0.73 |
| 3 | -0.59 |
| 4 | 1.17 |
| 5 | -1.40 |
| 7 | -0.21 |
| 8 | -0.34 |
| intercept | -3.36 |
+-----------+----------+
8 rows in set (0.00 sec)
Variable 9 Desired
+-----------+------------+
| variables | constant |
+-----------+------------+
| 1 | -0.54 |
| 2 | 2.32 |
| 3 | 1.87 |
| 4 | 1.92 |
| 5 | -2.31 |
| 6 | -1.02 |
| intercept | -4.6982666 |
+-----------+------------+
Variable 9 Actual
+-----------+----------+
| variables | constant |
+-----------+----------+
| 1 | -0.55 |
| 2 | 2.33 |
| 3 | 1.88 |
| 4 | 1.92 |
| 5 | -2.30 |
| 6 | -1.02 |
| 7 | 0.67 |
| 8 | -0.56 |
| 9 | 1.65 |
| intercept | -4.67 |
+-----------+----------+
10 rows in set (0.00 sec)
All I need to do is detect which variables are not the root variables and filter them out. How should this be accomplished?
In response to JNevill's answer:
For v.variables of 9
+-----------+-------+-------+----------+
| variables | depth | path | constant |
+-----------+-------+-------+----------+
| 1 | 3 | 9>7>1 | -0.55 |
| 2 | 3 | 9>7>2 | 2.33 |
| 3 | 3 | 9>7>3 | 1.88 |
| 4 | 3 | 9>8>4 | 1.92 |
| 5 | 3 | 9>8>5 | -2.30 |
| 6 | 2 | 9>6 | -1.02 |
| 7 | 2 | 9>7 | 0.67 |
| 8 | 2 | 9>8 | -0.56 |
| 9 | 1 | 9 | 1.65 |
| intercept | 1 | 9 | -4.67 |
+-----------+-------+-------+----------+
10 rows in set (0.00 sec)
I'm not going to attempt to fully wrap my head around what you are doing, and I would agree with #RickJames up in the comments that this feels like maybe not the best use-case for a database. I too am a little obsessive though. I get it.
There are couple of things that I almost always track in a recursive CTE.
The "Path". If I'm going to let a query head down a rabbit hole, I want to know how it got to the end point. So I track a path so I know which primary key was selected through each iteration. In the recursive seed (top portion) I use something like SELECT CAST(id as varchar(500)) as path... and in the recursive member (bottom portion) I do something like recursiveCTE.path + '>' + id as path...
The "Depth". I want to know how deep the iterations went to get to the resulting record. This is tracked by adding SELECT 1 as depth to the recursive seed and recursiveCTE + 1 as depth to the recursive member. Now I know how deep each record is.
I believe number 2 will solve your issue:
WITH RECURSIVE t
AS (
SELECT v.variables,
v.slope,
v.intercept,
1 as depth
FROM variables v
WHERE v.variables = XXXX
UNION ALL
SELECT v.variables,
vhsv.sign * t.slope * v.slope slope,
vhsv.sign * t.slope * v.intercept intercept,
t.depth + 1
FROM t
INNER JOIN variables_has_sub_variables vhsv ON vhsv.variables = t.variables
INNER JOIN variables v ON v.variables = vhsv.sub_variables
)
SELECT variables,
SUM(slope) constant
FROM t
WHERE depth > 1
GROUP BY variables
UNION
SELECT 'intercept' variables,
SUM(intercept) intercept
FROM t;
The WHERE clause here will restrict records in your recursive result set that have a depth of 1, meaning they were brought in from the recursive seed portion of the recursive CTE (That they are a root).
It wasn't clear if you required that the root be removed from your second UNION of your t CTE. If so, the same logic applies; just toss that WHERE clause on to restrict depth records of 1
While it may not be helpful here, an example of your recursive cte with PATH would be:
WITH RECURSIVE t
AS (
SELECT v.variables,
v.slope,
v.intercept,
1 as depth,
CAST(v.variables as CHAR(30)) as path
FROM variables v
WHERE v.variables = XXXX
UNION ALL
SELECT v.variables,
vhsv.sign * t.slope * v.slope slope,
vhsv.sign * t.slope * v.intercept intercept,
t.depth + 1,
CONCAT(t.path,'>', v.variables)
FROM t
INNER JOIN variables_has_sub_variables vhsv ON vhsv.variables = t.variables
INNER JOIN variables v ON v.variables = vhsv.sub_variables
)
SELECT variables,
SUM(slope) constant
FROM t
WHERE depth > 1
GROUP BY variables
UNION
SELECT 'intercept' variables,
SUM(intercept) intercept
FROM t;

Can't figure out a simple SQL query

Might be very simple, but I've been digging fow a few days now... I just can't figure out how to make this SQL query in Access...
In reference to the tables below, i'm looking for the query that can extract all the ITEMS for a specific Shop (ie 1:Alpha) from a specific GROUP (ie 1:Tools), that are NOT in the report for 2014... in this case ITEMS.IDs 6, 8, 9 and 10!
Tables:
Years
ID | Year
-----------------------------------------------
1 | 2014
2 | 2015
Shops
ID | ShopName
-----------------------------------------------
1 | Alpha
2 | Bravo
Items
ID | StockNbr | Description | GroupID
-----------------------------------------------
1 | 00-1200 | Ratchet 1/4 | 1
2 | 00-1201 | Ratchet 1/2 | 1
3 | 00-1300 | Screwdriver Philips No1 | 1
4 | 01-5544 | Banana | 2
5 | 00-4457 | Apple | 2
6 | 21-8887 | Hammer | 1
7 | 21-6585 | Drill | 1
8 | 21-4499 | Multimeter | 1
9 | 21-5687 | Digital Caliper | 1
10 | 22-7319 | File Set | 1
...
Groups
ID | GroupName
-----------------------------------------------
1 | Tools
2 | Fruits
REPORTS
ID | YearID | ShopID | ItemID
-----------------------------------------------
1 | 1 | 1 | 1
2 | 1 | 1 | 2
3 | 1 | 1 | 3
4 | 1 | 1 | 4
5 | 1 | 1 | 7
6 | 1 | 2 | 5
7 | 1 | 2 | 8
8 | 1 | 2 | 10
I've tried this, but then I realize it doesn't take the shops into consideration, it'll list all items that are not listed in reports, so if reports has an item for shop 2, it won't list it either...
SELECT Items.ID, Items.StockNbr, Items.Description, Items.GroupID, Reports.YearID, Reports.ShopID
FROM Reports
RIGHT JOIN Items ON Reports.ItemID = Items.ID
WHERE (((Items.GroupID)=1) AND ((Reports.UnitID) Is Null))
ORDER BY Items.StockNbr;
Thank you!
I think you're looking for an anti-join. There are several ways to do this. Here's one using not in.
select i.* from items i
where i.GroupId = 1
and i.ID NOT IN (
select ItemID from reports r
where r.ShopID = 1
and r.YearID = 2014
)
If the table Reports does not reference Items.ID then there is no available relationship ShopID or YearID
select *
from items
left join reports on items.id = reports.itemid
where reports.itemid IS NULL

SQL Server 2008, concatenating Strings?

I have wasted my 2 whole days to trying to resolve this issue, Now I am going out of my mind, I need an urgent Help,
The Issue is,
I Have To Tables
Table: Sales, SalesId is primary key
---------------------------------------------------
SalesId | SalesDate | Customer| Discount | Remarks
---------------------------------------------------
1 | 01/01/2012| John | 15 | NULL
2 | 01/01/2012| Peter | 25 | NULL
3 | 01/01/2012| Micheal | 35 | NULL
Table: SalesBody, SerialNo is primary key and SalesId is foreign key
---------------------------------------------------
SerialNo | SalesId | Product | Quantity | Rate
---------------------------------------------------
10 | 1 | Pencil | 18 | 20
11 | 1 | pen | 200 | 60
12 | 1 | Rubber | 150 | 10
13 | 1 | Paper | 500 | 2
14 | 2 | Mouse | 15 | 190
15 | 2 | KeyBoard | 10 | 600
16 | 2 | Monitor | 5 | 2000
17 | 3 | Mobile | 2 | 15000
Now I want to make a query which can make the result like following
----------------------------------------------------------------------------
SalesId | SalesDate | Details | Amount
----------------------------------------------------------------------------
1 | 01/01/2012 | Sold: Pencil x 18 # 20, Pen x 200 # 60| xxxxxxx
| | Rubber x 150 # 10, Paper x 500 # 2 |
2 | 01/01/2012 | Sold: Mouse x 15 # 190, Keyboard x 10 |
| | # 600, Monitor x 5 # 2000 | xxxxxxx
3 | 01/01/2012 | Sold: Mobile x 2 # 15000 | xxxxxxx
I have tried different techniques eg. Coalesce, Stuff, For XML PATH('')
I could not Concatenate the Detail String.
As far as I can see you just need to pivot the SalesBody table and group by SalesID
Something along the lines of the below query should do the trick
select sb.SalesId, ( SELECT ', ' + sb2.Product + ' x ' + sb2.Quantity + ' # ' + sb2.Rate
FROM SalesBody sb2
WHERE sb2.SalesId = sb.SalesId
FOR XML PATH('') ) AS Details
from SalesBody sb
group by sb.SalesId
Then just join that query with your Sales table to get the other data and do a STUFF command on Details in the query above to remove the leading "," and add your "sold: " string and you should be all good to go.

What can be the best model of SQL tables to keep rows of data with 82 columns?

I need to save measures coming from devices into a SQL database (SQL Server 2008). Each device gives, at a specific time, the same array of measures. An array is composed of 80 measures, that can be grouped.
To resume, at a specific time t(x), I have the following data (t(x) considered as one "session" of measures):
t(0): DeviceID, DateTime, 80 measures
t(1): DeviceID, DateTime, 80 measures
...
A device produces, in a session of measures t(x), 8 sets of same type of 10 measures (a, b, c, d, e, f, g, h, i, j) (a, b ,c ... representing the type of measures as int, float, double, etc..) corresponding of 8x10=80 measures in total.
Example:
set N°1 can be (10, 2, 3.2f, 4.76, "Data1", 3, 2, 2.2, 5.6f, 10.0f)
set N°2 can be (2, 4, 31.2f, 4.23, "Data2", 1, 1, 3.2, 2.2f, 2.1f)
....
set N°8 can be (10, 7, 1.1f, 2.35, "Data8", 8, 1, 2.1, 2.1f, 8.2f)
Note: the number of sets of measures, 8, will not change.
I would like to know what can be the best design of table(s) to handle these measures (insert, select, delete, no update)?
I thought about these possibilities:
It can be one table with 82 columns.
It can be one main table (DeviceID, DateTime) and 8 sub tables representing the 8 set of measures.
It can be one main table (DeviceID, DateTime) and 1 sub table that can have one set of measure, and a type to indicate which set of measures.
If every "session" consists of (8, either stable or not) number of sets where every "set" consists of (10, not-to-change) number of measurements (of possibly different types), I'd choose one table with fields:
CREATE TABLE deviceData
( deviceID INT
, sessionID INT
, setID INT
, a int
, b int
, c int
, d int
, e int
, f int
, g int
, h float
, i float
, j double
, PRIMARY KEY (deviceID, sessionID, setID)
) ;
You can also have a deviceSession, where the date or datetime field for every session can be stored:
CREATE TABLE deviceSession
( deviceID INT
, sessionID INT
, measureTime DATETIME
, PRIMARY KEY (deviceID, sessionID)
) ;
I would also add a foreign key constraint from deviceData to this table:
ALTER TABLE deviceData
ADD FOREIGN KEY (deviceID, sessionID)
REFERENCES deviceSession(deviceID, sessionID)
And every INSERT could be a transaction that inserts one row at deviceSession and 8 rows at deviceData.
Sample data:
+----------+-----------+-------+---+---+----+----+---+---+----+-----+-----+-----+
| deviceID | sessionID | setID | a | b | c | d | e | f | g | h | i | j |
+----------+-----------+-------+---+---+----+----+---+---+----+-----+-----+-----+
| 1 | 1 | 1 | 7 | 8 | -3 | 17 | 0 | 3 | -6 | 7.0 | 4.3 | 6.9 |
| 1 | 1 | 2 | 4 | 6 | 2 | 12 | 3 | 0 | -6 | 8.0 | 4.4 | 6.7 |
| 1 | 1 | 3 | 5 | 5 | -1 | 7 | 2 | 0 | -6 | 7.5 | 4.9 | 7.4 |
.................................................................................
| 1 | 1 | 8 | 0 | 9 | -6 | 29 | 0 | 7 | -6 | 7.8 | 6.3 | 7.3 |
| 1 | 2 | 1 | 5 | 4 | -6 | 29 | 9 | 7 | -6 | 7.9 | 6.3 | 4.3 |
| 1 | 2 | 2 | 4 | 3 | 2 | 12 | 3 | 0 | -6 | 8.0 | 4.4 | 6.7 |
| 1 | 2 | 3 | 5 | 5 | -1 | 8 | 2 | 0 | -6 | 7.5 | 4.9 | 7.4 |
.................................................................................
| 1 | 2 | 8 | 0 | 4 | -6 | 20 | 5 | 7 | -6 | 7.6 | 6.3 | 7.3 |
| 1 | 3 | 1 | 4 | 6 | 2 | 17 | 0 | 3 | -6 | 7.0 | 4.3 | 6.9 |
.................................................................................
.................................................................................
| 2 | 1 | 1 | 2 | 2 | -2 | 12 | 0 | 2 | -2 | 2.0 | 2.2 | 2.2 |
| 2 | 1 | 2 | 6 | 7 | -9 | 12 | 0 | 2 | -2 | 2.0 | 8.2 | 7.2 |
.................................................................................
.................................................................................
+----------+-----------+-------+---+---+----+----+---+---+----+-----+-----+-----+
If an a measure from one set of measures might generally be compared to an a from another set (either another set within the same measure group, or from a completely different set), than all of those a values ought to be stored in the same column. If this is the case, you should definitely rule out the 82 column wide table - any reasonably complex criteria in a WHERE clause could explode if you need to consider 8 a columns, 8 c columns and 8 f columns.
The key for this table would be {DeviceID, DateTime, SetNo}.
Choose a structure that fits the queries you need to do, the meaning of the data.
If you will be working with the sets of 10 then #ypercube's answer is good. If you are doing queries which tend to work with data from all the sets, the 80 values are in some sense a "unit" then 80 columns may actually be what your data means.