I have a table in access with the following format:-
ID | Name | Qty
----+--------+------
1 | A1 | 10
2 | A2 | 20
3 | A1 | 30
4 | A2 | 40
5 | A1 | 50
----+--------+------
I want to run a query which will return the sum of Qty for each row above it where the Name matches. So, the Output will be :-
ID | Name | Output
----+--------+---------
1 | A1 | 0
2 | A2 | 0
3 | A1 | 10
4 | A2 | 20
5 | A1 | 40
----+--------+----------
I am not being able to write the query. I think I need some kind of recursive query, but I'm not very well versed in SQL/Databases.
Access does not support recursion. The following query should do what you want (i called your table NameQty):
SELECT t1.Id,t1.name,sum(t2.Qty)
FROM NameQty t1
LEFT JOIN NameQty t2 ON t1.name=t2.name AND t1.Id>t2.Id
GROUP BY t1.Id,t1.name
ORDER BY t1.Id
I think you should also use some other column than ID for the definition of "above".
Related
There is a flag in mysql which enable/disable full group by (ONLY_FULL_GROUP_BY) But I am searching for same flag or connection string param to disable full group by in H2 database.
Here is my sample data.
+----+---------------+-----------------+
| ID | SYNC_ID | LIFECYCLE_EVENT |
+----+---------------+-----------------+
| 3 | 41 | 2 |
+----+---------------+-----------------+
| 2 | 41 | 1 |
+----+---------------+-----------------+
| 4 | 69 | 1 |
+----+---------------+-----------------+
| 5 | 69 | 3 |
+----+---------------+-----------------+
Here is my desired output:
+----+---------------+-----------------+
| ID | SYNC_ID | LIFECYCLE_EVENT |
+----+---------------+-----------------+
| 3 | 41 | 2 |
+----+---------------+-----------------+
| 5 | 69 | 3 |
+----+---------------+-----------------+
And Here is my query which I am trying to use for desired output
select id, sync_id, max(lifecycle_event)
from asset
where asset_type = 1
GROUP BY sync_id;
But it gives me ErrorCode: 90016 which means all non aggregate columns should be selected in group by. If I do so I get the wrong data results.
So Clearly I do not want to group by on id and sync_id . Please guide me how can I achieve this in H2 database.
There is no such thing in almost any other database -- because group by is not broken in those databases. You can phrase the query like this:
select a.*
from asset a
where asset_type = 1 and
lifecycle_event = (select max(lifecycle_event) from asset a2 where a2.sync_id = a.sync_id);
you can try below -
select max(id),sync_id, max(lifecycle_event)
from asset
where asset_type = 1
GROUP BY sync_id
I don't see any point in trying to emulate MySQL's broken group by implementation.
You can rewrite your query to
select a1.id, a1.sync_id, a2.max_even
from asset a1
join (
select sync_id, max(lifecycle_event) as max_event
from asset
group by sync_id
) a2 on a2.sync_id = a1.sync_id
and a2.max_event = a1.lifecycle_event;
So I am wondering. I fell into an interesting suggestion from another developer. So i basically have two tables I join in a query and I want the resulting table from the query to have an extra column that comes from the table on from the joint.
Example:
#table A: contains rating of players, changes randomly at any date depending
#on drop of form from the players
PID| Rating | DateChange |
1 | 2 | 10-May-2014 |
1 | 4 | 20-May-2015 |
1 | 20 | 1-June-2015 |
2 | 4 | 1-April-2014|
3 | 4 | 5-April-2014|
2 | 3 | 3-May-2015 |
#Table B: contains match sheets. Every player has a different match sheet
#and plays different dates.
MsID | PID | MatchDate | Win |
1 | 2 | 10-May-2014 | No |
2 | 1 | 15-May-2015 | Yes |
3 | 3 | 10-Apr-2014 | No |
4 | 1 | 21-Apr-2015 | Yes |
5 | 1 | 3-June-2015 | Yes |
6 | 2 | 5-May-2015 | No |
#I am trying to achieve this by running the ms-access query: i want to get
#every players rating at the time the match was played not his current
#rating.
MsID | PID | MatchDate | Rating |
1 | 2 | 10-May-2014 | 4 |
2 | 1 | 15-May-2015 | 2 |
3 | 3 | 10-Apr-2014 | 4 |
4 | 1 | 21-Apr-2015 | 4 |
5 | 1 | 3-June-2015 | 20 |
6 | 2 | 5-May-2015 | 3 |
This is what I have tried below:
Select MsID, PID, MatchDate, A-table.rating as Rating from B-table
left Join A-table
on B-table.PID = A-table.PID
where B-table.MatchDate > A-table.Datechange;
any help is appreciated. The solution can be in Vba as long as it returns something like a view/table I can manipulate using other queries or report.
Think of this in terms of sets of data... you need a set that lists the MAX dateChange for each player's and match date.
Soo...
SELECT MAX(A.DateChange) MDC, A.PID, B.Matchdate
FROM B-table B
INNER Join A-table A
on B.PID = A.PID
and A.DateChange <= B.MatchDate
GROUP BY A.PID, B.Matchdate
Now we take this and join it back to what you've done to limit the results in table A and B to ONLY those with that date player and matchDate (my inline table C)
SELECT B.MsID, B.PID, B.MatchDate, A.rating as Rating
FROM [B-table] B
INNER JOIN [A-table] A
on B.PID = A.PID
INNER JOIN (
SELECT MAX(Y.DateChange) MDC, Y.PID, Z.Matchdate
FROM [B-table] Z
INNER Join [A-table] Y
on Z.PID = Y.PID
and Y.DateChange <= Z.MatchDate
GROUP BY Y.PID, Z.Matchdate) C
on C.mdc = A.DateChange
and A.PID = C.PId
and B.MatchDate = C.Matchdate
I didn't create a sample for this using your data so it's untested but I believe the logic is sound...
Now Tested! SQL Fiddle using SQL server though...
My results don't match yours exactly. I think you're expected results are wrong though for MSID 4 given rules defined.
I have 2 tables, "table1" have 1 column to store "table2" column name. Table1 data as below:
ID | Desc | Table2ColName | Active
-------------------------------------
1 | 1 Day | D1 | Yes
2 | 2 Days | D2 | No
3 | 3 Days | D3 | Yes
Table2 data as below:
ID | ShopName | D1 | D2 | D3
----------------------------------
1 | Sp1 | 100 | 80 | 120
Then I want to join 2 table and just display the Active data, How do I using linq to query the result as below:
ID | ShopName | D1 | D3
---------------------------
1 | Sp1 | 100 | 120
I have try whole day but get noting, hope can help. Thanks
I assume you already got the answer you needed for this, but I figured id post it anyway. Your query should look something like this.
var results = from a in data.table1
join b in data.table2
on a.ID equals b.ID
where a.Active =='Yes'
select new
{
a.ID,
b.ShopName,
b.D1,
b.D2
};
t1
id | name | include
-------------------
1 | foo | true
2 | bar | true
3 | bum | false
t2
id | some | table_1_id
-------------------------
1 | 42 | 1
2 | 43 | 1
3 | 42 | 2
4 | 44 | 1
5 | 44 | 3
Desired output:
name | count(some)
------------------
foo | 3
bar | 1
What I have currently from looking through other solutions here:
SELECT a.name,
COUNT(r.some)
FROM t1 a
JOIN t2 r on a.id=r.table_1_id
WHERE a.include = 'true'
GROUP BY a.id,
r.some;
but that seems to get me
name | count(r.some)
--------------------
foo | 1
foo | 1
bar | 1
foo | 1
I'm no sql expert (I can do simple queries) so I'm googling around as well but finding most of the solutions I find give me this result. I'm probably missing something really easy.
Just remove the second column from the group by clause
SELECT a.name,
COUNT(r.some)
FROM t1 a
JOIN t2 r on a.id=r.table_1_id
WHERE a.include = 'true'
GROUP BY a.name
Columns you want to use in an aggregate function like sum() or count() must be left out of the group by clause. Only put the columns in there you want to be unique outputted.
This is because multiple column group requires the all column values to be same.
See this link for more info., Using group by on multiple columns
Actually in you case., if some are equal, table_1_id is not equal (And Vice versa). so grouping cannot occur. So all are displayed individually.
If the entries are like,
id | some | table_1_id
-------------------------
1 | 42 | 1
2 | 43 | 1
3 | 42 | 2
4 | 42 | 1
Then the output would have been.,
name | count
------------------
foo | 2 (for 42)
foo | 1 (for 43)
bar | 1 (for 42)
Actually, if you want to group on 1 column as Juergen said, you could remove r.some; from groupby clause.
i need some help to make a query in sql
suppose i have: table name: register
**id_r | name | text |**
1 | name 1 | text 1 |
2 | name 2 | text 2 |
and table name: details
**id_d | id_r | text_d |**
1 | 1 | text 1a |
2 | 1 | text 1b |
3 | 2 | text 2a |
and i need the result like:
**id_r | name | text | text_d_a | text_d_b |**
1 | name 1 | text 1 | text 1a | text 1b |
2 | name 2 | text 2 | text 2a
how can i do the sql statement to have something like this ??
It's possible:
SELECT
R.id_r, R.name, R.[text],
D1.text_d AS 'text_d_a',
D2.text_d AS 'text_d_b'
FROM
register R
LEFT JOIN details D1 ON R.id_r = D1.id_r AND D1.text_d LIKE '%a%'
LEFT JOIN details D2 ON R.id_r = D2.id_r AND D2.text_d LIKE '%b%'
I think it is bad idea to use this structure, because your query will depends tables data. You can implode text_d values with comma, for example:
SELECT t1.*,
(SELECT GROUP_CONCAT(t2.`text_d` SEPARATOR ',') FROM `details` as t2
WHERE t2.`id_r`=t1.`id_r`) as `text_d`
FROM `register` as t1