Add flag on SQL Server table, based on pair of features [duplicate] - sql

This question already has answers here:
Get top 1 row of each group
(19 answers)
Closed 8 months ago.
I have a table in SQL Server with Id, Code and Prod. I want to add a flag and end up like:
Id Code Prod Flag
0 101 A 0
1 101 B 0
2 101 A 1
3 101 A 1
4 101 B 1
5 160 B 0
6 160 A 0
7 160 B 1
8 190 A 0
9 190 B 0
For each pair Code-Prod (eg. 101-A, which has 3 cases), the flag should assume 0 for the first Id, 1 otherwise.
How do I do that?

This is ideally solved with row_number() window function, combined with an updatable CTE:
with upd as (
select *, Row_Number() over(partition by Concat(code,prod) order by id) rn
from t
)
update upd
set flag = case when rn = 1 then 0 else 1 end;

Related

Fetching data from DB and populate a partitioned List

I am confused about this both from front end point of view as well as querying the data from SQLite Database. If you have any idea how to solve either of these please do answer.
SQLite Database
I have a table likes this:
transactionId | productId | quantity
1 2 1
2 4 0
3 1 null
4 3 1
5 9 1
6 6 0
7 1 1
8 7 1
9 8 1
10 2 1
11 0 null
12 3 1
13 5 1
14 7 1
15 1 0
16 2 1
17 9 1
18 0 null
19 2 1
Now I want to display this data in groups of 5 units(i.e. groups till 5 units are completed) in list in my flutter app.
So 1st group will have 8 items,
2nd will have 6 items,
and 3rd group will have 5 items
(and is still incomplete since more items can be added till quantity for that group becomes 5)
Something like this:
Now my App can have multiple groups like this. Also, I don't think Grid view builder can work here since for each group I'll have to display some data for the group as well as accumulated data (which isn't shown in the picture)
Questions:
1) How to query data from SQFLite database?
2) How to display the queried data in my Flutter App front end?
Unfortunately, this type of problem requires a recursive CTE (or other iterative processing).
Assuming that transactionId is consecutive with no gaps:
with recursive cte as (
select transactionId, productId,
coalesce(quantity, 0) as quantity,
1 as bin
from t
where transactionId = 1
union all
select t.transactionId, t.productId,
(case when cte.quantity > 5
then 0 else cte.quantity
end) + coalesce(t.quantity, 0) as quantity,
(case when cte.quantity > 5 then 1 else 0 end) + cte.bin as bin
from cte join
t
on t.transactionId = cte.transactionId + 1
)
select *
from cte;
If transactionId has gaps or other issues, just use row_number() (in another CTE) to create an appropriate column for the where clauses.

TSQL Sum with type [duplicate]

This question already has answers here:
SQL Server dynamic PIVOT query?
(9 answers)
Closed 5 years ago.
I'm writing using translate
Table1
id number type
1 6 111
1 5 111
1 6 113
2 3 112
2 6 111
i need to sum group by value of "type" and "id"
the result I want to see
RESULT Table
id type111 type112 typ113
1 11 0 6
2 6 3 0
Another way to use pivoting:
SELECT id,
ISNULL([111],0) as Type111,
ISNULL([112],0) as Type112,
ISNULL([113],0) as Type113
FROM (
SELECT id,
number,
[type]
FROM Table1
) AS SourceTable
PIVOT (SUM(number) FOR [type] IN ([111], [112], [113])
) AS PivotTable;
Output:
id Type111 Type112 Type113
----------- ----------- ----------- -----------
1 11 0 6
2 6 3 0
(2 rows affected)
In case when the variety of types is high - use dynamic SQL to build and execute query.
Try using SUM with CASE:
SELECT ID,
SUM(CASE WHEN type = 111 THEN number END) AS type111,
SUM(CASE WHEN type = 112 THEN number END) AS type112,
SUM(CASE WHEN type = 113 THEN number END) AS typE113,
FROM TABLE1
GROUP BY ID

Add order within group and mark whether a row is the last in its group

I have a table in an SQL Server database on the following form, sorted according to id.
id group
1 10
17 10
24 10
2 20
16 20
72 20
104 20
8 30
9 30
I would like to select every row grouped according to the row group and add the following information to this table: the order (as sorted) within the group and whether the row is the last row in the group. In other words, something similar to this:
id group order last
1 10 1 0
17 10 2 0
24 10 3 1
2 20 1 0
16 20 2 0
72 20 3 0
104 20 4 1
8 30 1 0
9 30 2 1
I've tried fiddling around with ROW_NUMBER, but I'm not all that experienced with SQL Server and I can't get it to work. Does anyone have a suggestion?
Use ROW_NUMBER window function
select id,[group],
row_number()over(partition by [group] order by id) as [order],
case when row_number()over(partition by [group] order by id desc) = 1 then 1 else 0 end as Last
From yourtable

SQL Inner Join and Partitioning To obtain RowNumbers when matching

I have 2 tables. The first table 'a' the second 'b'.
I am writing a query that grabs every row in table a (there is 33 rows defined) and inner joins table b where the EnclLocation or the BackPanLoc match the Workcell in table A.
I only want a row from table B where they match based off BackPan and EnclLocation but they are not the same records. table b has a few rows of data that is assigned to the same workcell as table a. I am just trying to retrieve those additional rows and partition it.
I attached table a and table b. I also attached the desired results for this query with respect to Workcell 10 only as an example... As you can see, table B has 4 records that has either the EnclLocation or the BackPanLoc = 10. But my results only show the same DelvNumber 4 times. any help is most appreicated.
Table a
Table b
Incorrect Results
Desired Results (showing only Workcell 10 as an example)
workcell DelvNumber RowNum
1 447910-02 1
2 445710-01 1
2 445710-01 2
3 444291-01 1
3 444291-01 2
4 447910-03 1
4 447910-03 2
5 648020-01 1
6 647800-02 1
7 646920-01 1
7 646920-01 2
8 644830-4-8 1
8 644830-4-8 2
9 443990-01 1
10 645960-01-03 1
10 445710-11 2
10 445710-02 3
10 445710-09 4
Code Used
WITH ss
AS (SELECT a.*,
Row_number()
OVER(
partition BY a.workcell
ORDER BY a.workcell) AS rownum
FROM nwcurrent a
INNER JOIN nwdeliverables b
ON b.encllocation = a.workcell
OR b.backpanloc = a.workcell
WHERE ( b.status < 9
AND ( b.encllocation <> 0
OR b.backpanloc <> 0 )
OR a.delvnumber = '123' ))
SELECT *
FROM ss
copy and paste format
1 447910-02 1
2 445710-01 1
2 445710-01 2
3 444291-01 1
3 444291-01 2
4 447910-03 1
4 447910-03 2
5 648020-01 1
6 647800-02 1
7 646920-01 1
7 646920-01 2
8 644830-4-8 1
8 644830-4-8 2
9 443990-01 1
10 645960-01-03 1
10 445710-11 2
10 445710-02 3
10 445710-09 4
SQLFiddle
http://sqlfiddle.com/#!3/a8682/4
A new try...
SELECT a.workcell
,a.DelvNumber AS A_DelvNumber
,b.DelvNumber AS B_DelvNumber
,CASE WHEN a.DelvNumber<>b.DelvNumber THEN b.DelvNumber ELSE a.DelvNumber END AS DelvNumber_Resolved
,Row_number() OVER(partition BY a.workcell ORDER BY a.workcell) AS rownum
FROM NWCurrent a
INNER JOIN NWDeliverables AS b ON b.EnclLocation=a.WorkCell OR b.BackPanLoc=a.WorkCell
WHERE (b.status <9 AND (b.EnclLocation<>0 OR b.BackPanLoc<>0)OR a.DelvNumber='123')

Get a percentage of all in Access SQL

I have a table containing a list of features that will be implemented by a given team for a given release, with a flag to tell me if the feature is testable or not.
Sample data can be:
feature team rel testable
1 1 1 1
2 1 1 1
3 1 1 1
4 1 2 1
5 1 2 1
6 1 2 0
7 1 3 0
8 1 3 0
9 1 3 1
10 2 1 0
11 2 1 0
12 2 1 0
13 2 2 1
14 2 2 0
15 2 2 0
16 2 3 1
17 2 3 1
18 2 3 0
What I try to get is, for each team and each release, what is the percentage of testable feature (over the overall count of features for this team and release.
Ideally I would like to keep it as a single SQL query due to the way I designed the display of the result.
I went as far as this:
SELECT
MyTable.team AS team,
MyTable.rel AS rel,
(COUNT(*)*100 / (
SELECT COUNT(*)
FROM MyTable
WHERE
[MyTable].team = team
AND [MyTable].rel = rel
)
) AS result
FROM MyTable
WHERE
MyTable.team IN (1,2)
AND MyTable.rel IN (1,2,3)
AND MyTable.testable = 1
GROUP BY
MyTable.rel,
MyTable.team
ORDER BY
MyTable.team,
MyTable.rel
Here is the result I expect (I don't really care about the rounding)
team rel result
1 1 1 // all are testable for team 1 release 1
1 2 0.66 // 2 out of 3 are testable for team 1 release 2
1 3 0.33
2 1 0
2 2 0.33
2 3 0.66
My feeling is that I am not that far from the solution, but I am not able to fix it.
I would think a simple average function would work here; assuming all values in the testable field are 1 or 0 only.
oh and get rid of testable = 1 in where clause
I'm not sure if access will implicitly cast the Boolean... so this will enable the avg to work by converting the value to 1,0 explicitly.
SELECT
MyTable.team AS team,
MyTable.rel AS rel,
AVG(iif(Testable,1,0)) AS result
FROM MyTable
WHERE
MyTable.team IN (1,2)
AND MyTable.rel IN (1,2,3)
GROUP BY
MyTable.rel,
MyTable.team
ORDER BY
MyTable.team,
MyTable.rel
select y.team, y.rel, x.cnt/y.tot as res
from (
select t.team, t.rel, sum(x.cnt) as tot
from (
select team, rel, testable, count(*) as cnt
from table where team in (1,2) and rel in (1,2,3)
group by team, rel, testable) x
join table t on t.team = x.team and t.rel = x.rel
group by team, rel) y
You can try this.