Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have Process SQL Server table and some columns and their values.
ID Step StateID SenderNo
61cc2608-81b8-48a2-89ce-8887438985bb 9 125 1750069133
61cc2608-81b8-48a2-89ce-8887438985bb 8 120 1111111162
61cc2608-81b8-48a2-89ce-8887438985bb 5 116 1111111162
61cc2608-81b8-48a2-89ce-8887438985bb 2 115 3900383669
61cc2608-81b8-48a2-89ce-8887438985bb 1 113 1750069133
14dsfgd4-123d-21ds-86ds-124sgslkgj31 9 125 1750069133
14dsfgd4-123d-21ds-86ds-124sgslkgj31 8 120 1111111162
14dsfgd4-123d-21ds-86ds-124sgslkgj31 5 116 1111111162
14dsfgd4-123d-21ds-86ds-124sgslkgj31 2 115 3900383669
14dsfgd4-123d-21ds-86ds-124sgslkgj31 1 113 1750069133
21456qwf-674s-75df-53sg-125sdfsgsd47 5 116 1111111162
21456qwf-674s-75df-53sg-125sdfsgsd47 2 115 3900383669
21456qwf-674s-75df-53sg-125sdfsgsd47 1 113 1750069133
I want to get data according to highest Step value. Like that;
ID Step StateID SenderNo
61cc2608-81b8-48a2-89ce-8887438985bb 9 125 1750069133
14dsfgd4-123d-21ds-86ds-124sgslkgj31 9 125 1750069133
21456qwf-674s-75df-53sg-125sdfsgsd47 5 116 1111111162
I have no idea how to write the necessary T-SQL query in ASP.Net (C#)...
The first thing to do is to write the TSQL that you need. By my reckoning, that is:
select ID, Step, StateID, SenderNo
from (
select *, row_number() over(partition by ID order by Step desc) as [_row]
from Process) x where x.[_row]=1
Next, you need to talk to the server in code. I'm going to use "dapper" for convenience:
using(var conn = new SqlConnection(ConnectionString))
{
var rows = conn.Query<Process>(#"
select ID, Step, StateID, SenderNo
from (
select *, row_number() over(partition by ID order by Step desc) as [_row]
from Process) x where x.[_row]=1").ToList();
// ... use rows
}
where Process is a class you define with suitable ID, Step, StateID, SenderNo properties. Or you can avoid that via dynamic:
using(var conn = new SqlConnection(ConnectionString))
{
var rows = conn.Query(#"
select ID, Step, StateID, SenderNo
from (
select *, row_number() over(partition by ID order by Step desc) as [_row]
from Process) x where x.[_row]=1").ToList();
foreach(var row in rows)
{
Console.WriteLine(row.ID); // dynamic member resolution
Console.WriteLine(row.Step);
//...
}
}
There are lots of examples on the web showing how to query a database in ASP.NET but the query you want would be along the lines of
SELECT *
FROM (
SELECT *, rn = ROW_NUMBER() OVER(PARTITION BY id ORDER BY step DESC)
FROM tbl
) t
WHERE rn=1
Related
I have to do range selection to get some data, and I have this query. Thanks to this question 1 and this question 2
QUERY QUESTION 1
SELECT * FROM (SELECT ROW_NUMBER() OVER(ORDER BY DKUREG ASC) AS NUMBER,
SIMDTA.ACRDKL.*
FROM SIMDTA.ACRDKL
WHERE DKKDCB = 1403 AND DKCOB = 70 AND DKBKTG = 4011 AND DKTHRG = 2019)
AS A WHERE NUMBER > = 1 AND NUMBER < = 100
QUERY QUESTION 2
SELECT * FROM (SELECT ROW_NUMBER() OVER (ORDER BY DKUREG ASC) AS NUMBER,
SIMDTA.ACRDKL.*
FROM SIMDTA.ACRDKL
WHERE DKKDCB = 1403 AND DKCOB = 70 AND DKBKTG = 4011 AND DKTHRG = 2019)
AS A WHERE A.NUMBER BETWEEN 1 AND 100
I've managed to get all the 100 data in DBVisualizer with this query.
But when I paste the code into Visual Studio 2013, I got this
.
Try to run the original SQLs directly in Db2 without the Visual Studio/MsDb2Client. If it works fine, there might be a problem with the Visual Studio/MsDb2Client rewrite component. If so, you may need to contact Microsoft.
Thanks.
I am trying to do the following but I cannot manage to get it right yet :(.
I have these tables:
table1 -> tb1_id, tb1_name
Sample Data:
--------------
1 group1
2 group2
3 group3
4 group4
5 group5
table2 -> tb2_id, tb2_sector, tb2_tb3_id
Sample Data:
--------------
1 alpha 1
2 beta 2
3 gamma 2
4 delta 2
5 epsilon 4
table3 -> tb3_id, tb3_mid, tb3_section
Sample Data:
--------------
1 234 alpha,beta,gama,delta
This is the output that I am looking for:
Name Count %
------ ----- -----
group1 1 25%
group2 3 75%
group3 0 0%
group4 0 0%
group5 0 0%
Basically I need a split a column value delimited by a comma (tb3_section in table3) and then find the right group for each value (table2 gives me the group id to link with table1) and then do a total count by group and get the percentage (assuming total is 100%).
This is the query I tried so far:
I searched for split value samples and found one that does the split by creating a numbers table first:
create table numbers (
`n` INT(11) SIGNED
, PRIMARY KEY(`n`)
)
INSERT INTO numbers(n) SELECT #row := #row + 1 FROM
(SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) t,
(SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) t2,
(SELECT 0 UNION ALL SELECT 1) t8,
(SELECT #row:=0) ti;
Afterwards, I did this:
select tb3_section, count(1) from (
select
tb3_mid,
substring_index(
substring_index(tb3_section, ',', n),
',',
-1
) as tb3_section from table3
join numbers
on char_length(tb3_section)
- char_length(replace(tb3_section, ',', ''))
>= n - 1
) tb3_section_dashboard
group by 1
This doesn't give me the group count. Just does the split of tb3_section but doesn't give me the correct count and equivalent percentage. Any ideas will be much appreciate it thanks a lot.
LATEST UPDATE
First of all, I would like to thanks #eggyal for pointing me to the right direction and #Shadow for despise knowing that I was not taking the best approach, he came up with a quick fix to my problem. I managed to change the approach and removed the comma delimited values from table3. Instead now I add multiple rows for each new value (and added a constraint to avoid duplicates).
Now table3 looks like:
Sample Data:
--------------
1 234 alpha
2 234 beta
3 234 gama
4 234 delta
5 235 alpha
Here is the query I have taken from #shadow sample:
SELECT t1.tb1_name, COUNT(t3.tb3_section) AS no_per_group,
COUNT(t3.tb3_section) / t4.no_of_groups AS percentage
FROM t1 left
JOIN t2 ON t1.tb1_id=t2.tb2_tb3_id
INNER JOIN t3 ON t2.tb2_sector=t3.tb3_section>0
JOIN (SELECT COUNT(*) AS no_of_groups
FROM t3 INNER JOIN t2 ON t2.tb2_sector=t3.tb3_section>0) t4
GROUP BY t1.tb1_name
Instead of using find_in_set now I use = to match the exact value.
Now I get something like the following but the percentage looks odd and I miss a group that doesn't have a match:
Name no_per_group percentage
----- ------------- ----------
group1 2 0.1053
group3 3 0.1579
group4 3 0.1579
group5 3 0.1579
Although still I need something like:
Name Count %
------ ----- -----
group1 1 25%
group2 3 75%
group3 0 0%
group4 0 0%
group5 0 0%
Notice that if there is no match in a group, I still need to show that group.
Because I have thousands of records which are different from each other, I need to add another condition: where tb3_mid=234 . Likes this, the results are using to tb3_mid.
The best solution would be to redesign your table structure and move the data in the delimited values list to a separate table.
The quick solution is to utilise MySQL's find_in_set() function.
To get the total count of entries in the messages table (table3):
select count(*) as no_of_groups
from t3 inner join t2 on find_in_set(t2.tb2_sector,t3.tb3_section)>0
To get the counts per group, add a join to table1 and group by group name. To calculate the percentage, add the above query as a subquery:
select t1.tb1_name, count(t3.tb3_section) as no_per_group, count(t3.tb3_section) / t4.no_of_groups as percentage
from t1 left join t2 on t1.tb1_id=t2.tb2_tb3_id
inner join t3 on find_in_set(t2.tb2_sector,t3.tb3_section)>0
join (select count(*) as no_of_groups
from t3 inner join t2 on find_in_set(t2.tb2_sector,t3.tb3_section)>0) t4 --no join condition makes a Cartesian join
group by t1.tb1_name
I have a table with the following records ordered by timestamp
Id TimeStamp Action
-- --------- ------
1 #1 ActionType#1
2 #2 ActionType#2
3 #3 ActionType#2
4 #4 ActionType#1
5 #5 ActionType#3
. . .
. . .
. . .
52 #52 ActionType#1
53 #53 ActionType#2
. . .
I want to write a query that would return to me a set of records, only if the records are in a particular sequence order.
For example on the data above, I want a query to:
"Get when Action#2 occurred after Action#1, in sequence, as per timestamp order."
Should return to me:
##First matching sequence
2 #2 ActionType#1
3 #3 ActionType#2
##Second matching sequence
52 #2 ActionType#1
53 #3 ActionType#2
Note: This is in an ASP.NET application so LINQ style answers are welcome
I would consider an effective solution based on for loop over your table:
List<myRecordClass> myResults = new List<myRecordClass>();
for (int i = 1; i < myTable.Count; i++)
{
if (myTable.ElementAt(i).Action == myTable.ElementAt(i-1).Action)
{
myResults.Add(myTable.ElementAt(i - 1));
myResults.Add(myTable.ElementAt(i));
}
}
This would allow you to implement other tests involving for example 3 consecutive records.
You can do it at Sql server side and reduce the size of resultset this way.
First find islands of constant Action when ordered by TimeStamp and them filter only islands of length= 2
select Id,TimeStamp, Action
from (
select *, cnt = count(*) over(partition by grp)
from (
select *, grp = row_number() over(order by TimeStamp) - row_number() over(partition by Action order by TimeStamp)
from (values
(1 ,'#1' ,'ActionType#1'),
(2 ,'#2' ,'ActionType#2'),
(3 ,'#3' ,'ActionType#2'),
(4 ,'#4' ,'ActionType#1'),
(5 ,'#5' ,'ActionType#3'),
(51,'#51','ActionType#2'),
(52,'#52','ActionType#2'),
(53,'#53','ActionType#2')
) t (Id,TimeStamp,Action)
) t1
) t2
where cnt=2
order by TimeStamp
I didn't check it (so I'll be happy to know if it works to you; I'm writing in mySQL):
SELECT a.Id, a.Id+1, a.Action
FROM #yourTable a
INNER JOIN #yourTable (same one as above) b
ON (a.Id=b.Id-1) AND (a.Action=b.Action);
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I have a complicated query for simple thing, but I have managed to make it to work. The query works when idclient is 1, but when idclient is 5 there is a problem.
Problem is that that client didn't order anything, he just paid some amount. So there isn't a.price, practically whole table is blank, and I want result like -1200,00 or paid amount in minus. My problem is that first part of table does not exist so inner join is impossible, and there for second part is also non existing. Any suggestion for a "quick fix"? :)
SELECT SUM(a.price) - s.pay AS Remain
FROM (SELECT name,
( quantity * itprice ) * ( 100 - percent ) / 100 AS price,
idclient
FROM (SELECT order.iditem AS ID,
item.name,
SUM(order.quant) AS quantity,
order.percent,
item.itprice,
order.idclient
FROM item
inner join order
ON order.iditem = item.id
WHERE ( order.idclient = 1 )
GROUP BY order.iditem,
order.percent,
item.name,
item.itprice,
order.idclient) AS X) AS a
inner join (SELECT SUM(amount) AS Pay,
idcom
FROM payed
WHERE ( idcom = 1 )
GROUP BY idcom) AS s
ON a.idclient = s.idcom
GROUP BY s.idcom,
a.idclient,
s.pay
(there is maybe some typing error in code, but don't bother because I have translated my original code, so maybe some letter is lost in translation. Code is correct)
Is this always just fetching one row? At least it looks like it, and if that's the case you could just use variables with something like this:
declare #price decimal(10,2) = 0, #payment decimal(10,2) = 0
SELECT
#price = SUM(order.quant * item.itprice ) * ( 100 - order.percent ) / 100)
FROM
item
inner join order
ON order.iditem = item.id
WHERE
order.idclient = 1
SELECT
#payment = SUM(amount)
FROM
payed
WHERE
idcom = 1
select #price - #payment
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I'd like to retrieve an integer value in a SQL Select but only when the data changes, e.g.:
Table data:
50 50 50 52 50 30 30 35 30 30 60 65 60 60
Now I'd like to get this data:
50 52 50 30 35 30 60 65 60
Executing a distinct query, this would not work for me because it would retrieve:
50 52 30 35 60 65
Any ideas?
I'm working with Entity Framework and C#, so suggestions using them would also be appreciated!
Thanks.
List<int> list=...;
var result=Enumerable.Range(0, list.Count- 1)
.Where(x=> x== list.Count-1 || list[x]!=list[x+1])
.Select(x=>list[x]);
fetch your results to dbResults then do
var results = new List<int>();
foreach (var element in dbResults)
{
if(!results.Any() || results.Last() != element)
{
results.Add(element);
}
}
int results will be list without consecutive duplicates
you can check it on ideone
This method is similar in principle to #wudzik's but instead of checking your result list each time, it simply stores the last int in a variable and checks against that instead.
var result = new List<int>();
int? previous;
foreach (var number in data)
{
if(!previous.HasValue || number != previous.Value){
{
result.Add(number);
previous = number;
}
}
return result
WITH cte as (--cte is your test data
SELECT
1 id,
50 value UNION SELECT
2,
50 UNION SELECT
3,
50 UNION SELECT
4,
52 UNION SELECT
5,
50 UNION SELECT
6,
30 UNION SELECT
7,
30 UNION SELECT
8,
35 UNION SELECT
9,
30 UNION SELECT
10,
30 UNION SELECT
11,
60 UNION SELECT
12,
65 UNION SELECT
13,
60 UNION SELECT
14,
60
),
temp AS --temp numbers the rows
( SELECT
id,
value,
ROW_NUMBER() OVER (ORDER BY id) rowno
FROM cte
)
SELECT
t2.value
FROM temp t1
INNER JOIN temp t2
ON t1.rowno = t2.rowno - 1 --join to the next row using rownumber
AND t1.value <> t2.value --but only return different values