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 5 years ago.
Improve this question
Here is Database picture
Click here to Show Picture
Back-end Code of my Design
if (startdate.Text == "" || enddate.Text == null)
{
MessageBox.Show("Please Select The Date");
}
else
{
con.Open();
SqlCommand cmd = new SqlCommand("Here i need query for total bags", con);
SqlDataReader reader = cmd.ExecuteReader();
reader.Read();
string val = reader.GetValue(0).ToString();
decimal valu = Convert.ToDecimal(val);
Int32 value = Convert.ToInt32(valu);
bags.Text = value.ToString();
con.Close();
}
Design of my app
i need to fetch total bags,sales and profit Click here to Show Design
Here i Need to fill values
also queries that i need
(1) sum of bags by selected Dates
(1.1) sum of bags by selected Name and Dates
(2) sum of credit by selected Dates
(2.1) sum of credit by selected Name and Dates
(3) sum of profit by selected Dates
(3.1) sum of profit by selected Name and Dates
Here it is Over all Data Query
select r.id,r.datee,r.time,c.name,r.description,r.vanda,r.bag,r.price,r.credit,r.debit from records as r, customer as c where r.cusid = c.id and c.name = 'aizaz' and r.datee between '1/1/2016' and '12/12/2017' order by r.datee asc;
select sum(r.bag) as SumOfBags
from records as r, customer as c
where r.cusid = c.id and c.name = 'aizaz' and r.datee between '1/1/2016' and '12/12/2017'
I'm almost sure that is about to work :)
In case of problems with empty elements you can try
select sum(r.bag) as SumOfBags
from records as r
inner join customer as c
on r.cusid = c.id
where r.datee between '1/1/2016' and '12/12/2017' and c.name = 'aizaz'
Super quick guide to SQL :)
The easiest query goes like this:
select <List of columns you want to be shown>
from <table name>
where <conditions you want>
If you want to get sum you need to write sum(<column to be sumed>) as <alias for this column> And you need to use this construction AS ONE OF THE COLUMNS YOU WANT TO BE SHOWN (after select). Like in example of 1.1
1)
Select Dates, Names, sum(bag) as SumOfBags
from TableName
group by Dates
1.1)
Select Dates, sum(bag) as SumOfBags
from TableName
group by Dates, Names
Of if you want to just select single value
1)
Select sum(bag) as SumOfBags
from TableName
where Date = WhatEverYouWant
1.1)
Select sum(bag) as SumOfBags
from TableName
where Dates = WhatEverYouWant and Names = WhatEverYouWant
I belive you are able to create other queries now :)
Related
I'm programming a C# Windows Forms Application in Visual Studio and I'm trying to get data about prices of products and the amount a user has added a product to its shopping list from my local MySQL-database into a List(int).
What I do is following:
If a user has added a product 4 times to their shopping list, I'm adding the barcode of the product 4 times to my List(int).
This is working but when I'm reading out all items of the List with the String.Join()-method into the IN-clause of my query and execute it, it only returns a row one time altough the IN-operator has the same barcode multiple times.
The following is how I'm adding barcodes to my List(int)
int count = 0;
List<int> barcodes = new List<int>();
MySqlCommand cmd = new MySqlCommand("SELECT product_barcode, amount FROM shopping_list_items WHERE shopping_list_id = " + current_shoppingListID + ";", db.connection);
cmd.ExecuteNonQuery();
var reader = cmd.ExecuteReader();
while (reader.Read())
{
do
{
barcodes.Add(Int32.Parse(reader["product_barcode"].ToString()));
count++;
} while (count < Int32.Parse(reader["amount"].ToString()));
}
reader.Close();
This is how I'm executing my query and assign the values to variables:
MySqlCommand cmdSum = new MySqlCommand("SELECT sum(price) AS 'total', supermarket_id FROM prices WHERE barcode IN (" + String.Join(", ", barcodes) + ") GROUP BY supermarket_id;", db.connection);
cmdSum.ExecuteNonQuery();
var readerSum = cmdSum.ExecuteReader();
while (readerSum.Read())
{
switch (double.Parse(readerSum["supermarket_id"].ToString()))
{
case 1:
sumSupermarket1 = double.Parse(readerSum["total"].ToString());
break;
case 2:
sumSupermarket2 = double.Parse(readerSum["total"].ToString());
break;
case 3:
sumSupermarket3 = double.Parse(readerSum["total"].ToString());
break;
}
}
A simplified query just to make it simple may look like this:
SELECT name FROM products WHERE barcode IN (13495, 13495, 13495);
If the above one is my query then I want it to return 3 the same rows.
So my question now is, how can I get multiple rows altough I use a same value multiple times in the IN-clause of a MySQL-query?
Q: how can I get multiple rows altough I use a same value multiple times in the IN-clause of a MySQL-query?
A: We don't. That's not how IN () works.
Note that
WHERE foo IN ('fee','fi','fi','fi')`
Is shorthand for
WHERE ( foo = 'fee'
OR foo = 'fi'
OR foo = 'fi'
OR foo = 'fi'
)
Understand what's happening here. MySQL is going to examine each row, and for each row it checks to see if this condition returns TRUE or not. If the row satisfies the condition, the row gets returned. Otherwise the row is not returned.
It doesn't matter that a row with foo value of 'fi' satisfies multiple conditions. All MySQL cares about is that the condition inside the parens ultimately evaluates to TRUE.
As an illustration, consider:
WHERE ( t.picked_by = 'peter piper'
OR t.picked_amount = 'peck'
OR t.name LIKE '%pickled%'
OR t.name LIKE '%pepper%'
)
There could be a row that satisfies every one of these conditions. But the WHERE clause is only asking if the entire condition evaluates to TRUE. If it does, return the row. If it doesn't, then exclude the row. We don't get four copies of a row because more than one of the conditions is satisfied.
So how do we get a set with multiple copies of a row?
As one possible option, we could use separate SELECT statements and combine the results with UNION ALL set operator. Something like this:
SELECT p1.name FROM product p1 WHERE p1.barcode IN (13495)
UNION ALL
SELECT p2.name FROM product p2 WHERE p2.barcode IN (13495)
UNION ALL
SELECT p3.name FROM product p3 WHERE p3.barcode IN (13495)
Note that the result from this query is significantly different than the result from the original query.
There are other query patterns that can return an equivalent set.
FOLLOWUP
Without an understanding of the use case, the specification, I'm just guessing at what we are attempting to achieve. Based on the two queries shown in the code (which follows a common pattern we see in code that is vulnerable to SQL Injection),
The shopping list:
SELECT i.product_barcode
, i.amount
FROM shopping_list_item i
WHERE i.shopping_list_id = :id
What is amount? Is that the quantity ordered? We want two cans of this, or three pounds of that? Seems like we would want to multiply the unit price by the quantity ordered to get the cost. (Two cans is going to cost twice as much as one can.)
If what we are after is the total cost of the items on the shopping list from multiple stores, we could do something like this:
SELECT SUM(p.price * s.amount) AS `total`
, p.supermarket_id
FROM ( SELECT i.product_barcode
, i.amount
FROM shopping_list_item i
WHERE i.shopping_list_id = :id
) s
JOIN price p
ON p.barcode = s.product_barcode
GROUP
BY p.supermarket_id
Note that if a particular product_barcode is not available for particular supermarket_id, that item on the list will be excluded from the total, i.e. we could get a lower total for a supermarket that doesn't have everything on our list.
For performance, we can eliminate the inline view, and write the query like this:
SELECT SUM(p.price * i.amount) AS `total`
, p.supermarket_id
FROM shopping_list_item i
JOIN price p
ON p.barcode = i.product_barcode
WHERE i.shopping_list_id = :id
GROUP
BY p.supermarket_id
If we absolutely have to rip through the shopping list query, and then use the rows from that to create a second query, we could form a query that looks something like this:
SELECT SUM(p.price * i.amount) AS `total`
, p.supermarket_id
FROM ( -- shopping_list here
SELECT '13495' AS product_barcode, '1'+0 AS amount
UNION ALL SELECT '13495', '1'+0
UNION ALL SELECT '13495', '1'+0
UNION ALL SELECT '12222', '2'+0
UNION ALL SELECT '15555', '5'+0
-- end shopping_list
) i
JOIN price p
ON p.barcode = i.product_barcode
WHERE i.shopping_list_id = :id
GROUP
BY p.supermarket_id
You would probably be better off investigating LINQ to SQL rather than using direct SQL and injection.
You can use an inline table join to accomplish what you want:
"SELECT sum(price) AS 'total', supermarket_id
FROM (select "+barcodes[0]+"as bc union all select "+String.Join(" union all select ", barcodes.Skip(1).ToArray())+") w
JOIN prices p ON p.barcode = w.bc
GROUP BY supermarket_id;"
Note: If you can name the column with the inline table alias (I couldn't test that) you could simplify the inline table generation.
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 7 years ago.
Improve this question
I am having a database where i have stored fees collected from several students.
I am having column like:-
admno name class section tuitionfee
SJS001 Arjun nursery a 3000
SJS002 akash nursery a 2000
SJS001 arjun nursery a 1000
SJS005 baldev class-II b 5000
There may be a same admission number who might have paid several times his tuition fees.
Now i want only to print the last value of all the entered admission number how can i do this.
If you want to print the last admission, you need to add column admissionDate. Then you can do something like this:
SELECT TOP(1) admno,name,class,section,tuitionfee, ADMISSIONDATE
FROM table_name
Where admno = 'SJS001'
Order by ADMISSIONDATE desc
This is Sql Server specific syntax. There are other ways to achieve this result, Like using MAX(ADMISSIONDATE) in subquery.
select *
from a t1
where
t1.admno = 'SJS001' And
ADMISSIONDATE = (select max(ADMISSIONDATE) from a t2 where t1.admno = t2.admno)
Assuming you have an Id column in your db to order entries by, then
In SQL:
SELECT * from YOUR_TABLE
where id in
(select max(id)
from YOUR_TABLE
group by admno)
In Linq:
var ids = YOUR_TABLE.GroupBy(y => y.admno).Select(y => y.Max(z => z.Id));
var result = YOURT_TABLE.Join(ids, x => x.Id, y => y, (x,y) => x);
I want to write an SQL statement that will:
Count the number of rows in the table booking that are open and where the booking.postcode is "MK"
Take a note of the plot (in booking.plot_id), and then update the table plot.jobs with the value count
For example running the SQL query when booking table has the following rows:
Would see the following highlighted values in plot.jobs being updated to 1:
This my code so far (note I am using Connector/Net):
public int CountBooking()
{
string query = "SELECT Count(*) FROM booking WHERE postcode=MK AND status=open";
int count = -1;
// ExecuteScalar will return one value
var cmd = new MySqlCommand(query, _connection);
count = int.Parse(cmd.ExecuteScalar() + "");
// Close
CloseConnection();
return count;
}
If there were 3 rows with a plot_id of 4, and 6 rows with a plot_id of 6, then the highlighted values will be updated to 3 and 6 respectively.
How would I go about achieving it?
You are close on the first part. If you want the number of openings for each plot_id, you'll need to use that in your GROUP BY statement like this:
SELECT plot_id, COUNT(*) AS numOpenings
FROM bookings
WHERE postcode = 'MK' AND status = 'open'
GROUP BY plot_id;
You can use that as a subquery in your UPDATE statement by joining it to the plot table and updating the matching rows, like this:
UPDATE plot p
JOIN(
SELECT plot_id, COUNT(*) AS numOpenings
FROM bookings
WHERE postcode = 'MK' AND status = 'open'
GROUP BY plot_id) temp ON temp.plot_id = p.plot_id
SET p.jobs = temp.numOpenings;
This worked out in SQL Fiddle. Let me know if you have more problems.
Never used Connector/Net but I would do something like this:
Run this query to retrieve the plot_id and JobCount:
select plot_id, count(*) JobCount from booking where postcode = 'mk' and status = 'open' group by plot_id;
Then scroll through this result set and issue update commands like this:
Update Jobs set jobs = [JobCount] where plot_ID = [plot_id]
Note the values of [JobCount] and [plot_id] will come from your first query.
I have a question regarding my SQL query. Below you will see my database:
And I have the following query right now:
SELECT enquete_vraag,enquete_antwoord,docent,vak,semesterstart
FROM ENQUETE_ANTWOORD
LEFT JOIN KDV ON ENQUETE_ANTWOORD.kdv_ID = KDV.kdv_ID
LEFT JOIN DOCENT ON KDV.docent_ID = DOCENT.docent_ID
LEFT JOIN VAK ON KDV.vak_ID = VAK.vak_ID
LEFT JOIN ENQUETE_VRAAG ON ENQUETE_ANTWOORD.enquete_vraag_ID = ENQUETE_VRAAG.enquete_vraag_ID
WHERE DOCENT.docent_ID = variableDocentID AND VAK.vak = variableVak
And I display the returned data in a datagridview:
Now the datagridview shows all questions that are being answered by all students. What I want is the average for each question and only show that. So you have 1 row that has question 6 with the average answer and question 7 with the average answer and so on, how do I achieve that in my SQL query?
hi you should do something like this
SELECT enquete_vraag,AVG(enquete_antwoord) enquete_antwoord,docent,vak,semesterstart
FROM ENQUETE_ANTWOORD
LEFT JOIN KDV ON ENQUETE_ANTWOORD.kdv_ID = KDV.kdv_ID
LEFT JOIN DOCENT ON KDV.docent_ID = DOCENT.docent_ID
LEFT JOIN VAK ON KDV.vak_ID = VAK.vak_ID
LEFT JOIN ENQUETE_VRAAG ON ENQUETE_ANTWOORD.enquete_vraag_ID = ENQUETE_VRAAG.enquete_vraag_ID
WHERE DOCENT.docent_ID = variableDocentID AND VAK.vak = variableVak
GROUP BY enquete_vraag, docent,vak,semesterstart
SELECT enquete_vraag,AVG(enquete_antwoord) as [enquete_antwoord]
FROM ...
GROUP BY enquete_vraag
The problem then, of course, becomes which vak etc to choose.... Because of translation, it is not easy for me to guess at which value means what, so it is hard to advise on that. You might be able to include the extra values in the GROUP BY clause (if they are the same for all the matching rows); or you might be able to take a MIN / MAX.
just add avg function in your code.
...AVG(enquete_antwoord)...
write above code it gives you the correct answer
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 8 years ago.
Improve this question
can someone please tell me why i am getting an error with this code ?
SqlCommand scGetClaimedDetails = new SqlCommand(
"SELECT SUM(isclaimable) as claimable, SUM(isclaimed) as claimed,SUM(total) as total from" +
" ( SELECT CASE WHEN claimed = 'Y' THEN inv_amt *.45 END as isclaimed, (inv_amt *.45) as inclaimable, inv_amt as total from invasset" +
" INNER JOIN Invoice ON invoice.invoice = invasset.invoice WHERE invasset.asset_no = #AssetNumber ) as D2", DataAccess.AssetConnection);
In subquery specifiy where is inv_amt column coming from (is it invoice.inv_amt or invasset.inv_amt)
ambigous column name inv_amt
It seams like the two tables invasset and Invoice both contains the column inv_amt, You have to reference it to an alias in the inner SELECT statement, something like: invoice.inv_amt or invasset.inv_amt:
SELECT SUM(isclaimable) as claimable, SUM(isclaimed) as claimed,
SUM(total) as total
FROM
(
SELECT CASE WHEN claimed = 'Y' THEN invoice.inv_amt *.45 END as isclaimed,
(inv_amt *.45) as inclaimable, inv_amt as total
from invasset INNER JOIN Invoice ON invoice.invoice = invasset.invoice
WHERE invasset.asset_no = #AssetNumber
) as D2
When I format your code to be human-readable...
SqlCommand scGetClaimedDetails = new SqlCommand(
"SELECT
SUM(isclaimable) AS claimable,
SUM(isclaimed) AS claimed,
SUM(total) AS total
FROM
(SELECT
CASE WHEN claimed = 'Y' THEN inv_amt *.45 END AS isclaimed,
(inv_amt *.45) AS inclaimable,
inv_amt AS total
FROM
invasset
INNER JOIN Invoice ON invoice.invoice = invasset.invoice
WHERE
invasset.asset_no = #AssetNumber) AS D2",
DataAccess.AssetConnection);
I can't help but notice that your outer SELECT is looking for a column called isclaimable while your inner SELECT is returning a column called inclaimable. There's a typo in your code.
Edit: In response to your comment on the question, which tables contain the field inv_amt? Clearly you're referencing two tables which have it. Since the only tables you're referencing are invasset and Invoice then clearly both of those tables have a column named inv_amt. You'll have to specify which one you want in your query.
So instead of:
`inv_amt AS total`
You'd want something like:
`invasset.inv_amt AS total`
(Assuming that's the table you want, otherwise use the other table.)