I've got a huge table, containing three "selection"-columns and many "data"-columns.
ID Thing1 Thing2 Thing3 avgData1 avgData2 highestEtc
---- -------- -------- -------- ---------- ---------- ------------
1 1 2 2 321 654 999
2 2 1 1 123 456 11
3 2 1 1 987 789 77
4 2 1 1 765 567 11
In my queries, I'm now selecting all entries with "Thing1" = x, "Thing2" = y, "Thing3" = z (Those three columns are selection-criteria.)
The purpose of getting those lines is to perform an action on each of the following data-columns: If it starts with "avg", I want to calculate an average of the specific column on all selected entries. On another prefix I want to count which number appears the most.
Is there a way of letting the MySQL Database do all this for me? I need a SQL-Statement that calculates the averages of the columns automatically, and performs other actions too.
For example, let's say I'd select the criteria Thing1=2, Thing2=1 and Thing3=1. Is there a way of writing the statement so that it returns only ONE entry, with the calculated things?
Result
----------------- ----------------- ----
(123+987+765)/3 (456+789+567)/3 11
I heard that this should be possible, and that it is a bad method of NOT letting the database perform those actions directly. Unfortunately, I have no idea how to do it.
Try this:-
SELECT ID, AVG(avgData1) AS RESULT1, AVG(avgData2) AS RESULT2, highestEtc
FROM YOUR_TAB
WHERE Thing1 = 2
AND Thing2 = 1
AND Thing3 = 1
GROUP BY ID
HAVING COUNT(highestEtc) > 1;
Hope this helps you.
Related
So first of all, I have 2 table. The first one is the categories
Id Name
------------
1 Interior
2 Eksterior
3 Display
then the secon table is history which the data is the task I've finished
Id category_name category_id date (month) User Id
---------------------------------------------------------------
001 Interior 1 3 1084
002 Eksterior 2 3 1084
003 Interior 1 4 1089
004 Eksterior 2 4 1085
005 Display 3 4 1085
and what I want is to get categories by month, user id and know which one already done and not done from history, like this
example the data in March with user id 1084 :
Id Name Status
---------------------------
1 Interior done
2 Eksterior done
3 Display not done
or like this :
Id Name Status
--------------------------
1 Interior 1
2 Eksterior 1
3 Display 0
if the category in history table exist, the status will be 1 for done and 0 for not done.
this is my query before :
SELECT c.id, c.category, c.id=h.category_id status FROM categories c, history h WHERE MONTH(h.created_at)
I keep retrieving the wrong result for my query. Please help me..
Seems like:
SELECT *
FROM
categories c
LEFT JOIN history h on h.category_id = c.id AND h."date (month)" = 3
..will get you towards what you want: there will be NULL in the row from history table, for category Display; you can use this "is or is not null" to create your done/not done column
I have 3 tables
1.Franchiese
Id Name
1 Vivek
2.Purchase
Id Fran_id commission_amount
1 1 100
2 1 1
3.Fran_payment
Id Fran_id amount
1 1 50
My SQL Query is
select franchiese.id,franchiese.name,sum(fran_payment.amount) as paid,sum(purchase.commission_amount) as tot,sum(purchase.commission_amount)-sum(fran_payment.amount) as rem from franchiese left join fran_payment on franchiese.id=fran_payment.fran_id left join purchase on franchiese.id=purchase.fran_id
It's giving me
Id Name Tot Paid Rem
1 vivek 101 100 1
Expected Answer
Id Name Tot Paid Rem
1 vivek 101 50 51
I think you have two identical entries in the Fran_payment table. Your SQL statement should work as intended, and is giving you logically correct values, but I think you have unexpected data in your table.
You are joining 3 tables which have unequal number of rows. Purchase table has 2 rows, while fran_payment has only one. At the time of join, the row in fran_payment is repeated to match the number of rows in purchase. Hence the row is duplicated and sum becomes 50 + 50 = 100 and your data would look like something like this-
ID | Name | fran_payment.amount | purchase.comission_amount
1 | Vivek | 50 | 100
1 | Vivek | 50 | 1
Try something like this
Select fran_id, sum(fran_payment.amount) as paid from purchase;
This should work.
Also, you'll need to run a sub query to only fetch data for given entry. Or, normal sum function would return the sum of while column, irrespective of the ID.
Select id, sum(fran_payment.amount from fran_payment where fran_payment.fran_id = id) as paid from franchise;
I hope that works. All the best.
PS: It's franchise, not franchiese.
I have a result set that contains; order_ids, a total for that order, and the quantities of items within.
Some totals are negative (if a refund has occurred) and others are positive. I would like to work out a count of the orders who's order_total, doesn't net out with with the negative values.
orders_id order_total products_quantity customers_id
--------- ------------- ----------------- --------------
1140898 -99.95830000 -1 459800
1140868 99.95830000 1 459800
1140867 99.95833333 1 459800
866932 -106.33333333 -2 459800
860100 125.08333333 3 459800
857864 106.33333333 2 459800
Would result in
orders_id order_total products_quantity customers_id
--------- ------------- ----------------- --------------
1140867 99.95833333 1 459800
860100 125.08333333 3 459800
I've attempted to write a cursor to iterate over each result, storing the last order_total and checking the current row for a diff.
This works as long as the negative order comes before or after the positive. Unfortunately, this wont always be the case.
Can anyone explain what approach/methods I should adhere to ensure the output below is achieved?
Based on your description, the problem is impossible. Consider:
orders_id order_total customers_id
--------- ------------- --------------
1 -100 1
2 50 1
3 50 1
4 50 1
(I assume that you only want to consider that each value only affects the "net" for a specific customer)
In the case above, orders_id=1 might be considered to offset 2 and 3 leaving 4 in the output, 3 4 leaving 2 in the output, or 2 and 4 leaving 3 in the output.
What if the lines with negative amounts are not an exact amount match for one or more of those with positives? Even if some combination of the negatives adds up to some combination of the positives, you would need to try every possible combination - just calculating the order of that algorithm makes my head hurt (O(N!)^2 I think).
I am designing a database to organize materials for 3D production.
Materials are named like 1_Fabric_01_Textile_001_BlueJeans_Denim and 2_Metal_02_BrushedMetal_002_ChromeBrushed_Chrome, etc
So, I need a materials table, which basically has information on material name (last value, look above) and a combination of type and subvariant. Each type has allowed variants like 1_Fabric has 01_Textile, 02_Leather, 2_Metal has 01_Metal, 02_BrushedMetal and so on.
Now making all combinations would not be difficult (i.e., being able to choose every possible subvariant for every material type), but I want to limit the combinations to only allowed combinations, so users cannot choose invalid combinations (like 1_Fabric_01Metal or 2_Metal_01Textile).
Any ideas?
In order to generate those kind of name
1_Fabric_01_Textile
2_Metal_02_BrushedMetal
Based on the followin tables
Type
----------
Id Name
-- ------
1 1_Fabric
2 2_Metal
SubType
------------
Id Name
-- ------
1 01_Textile
2 02_Leather
3 01_Metal
4 02_BrushedMetal
And keeping rules on what types can relate to subtypes
You ill need a relational table like:
Type_SubType
-----------------
TypeId SubTypeId
------ ---------
1 1
1 2
2 3
2 4
and if you need more levels of subtypes you can add more tables
1_Fabric_01_Textile_001_BlueJeans_Denim
2_Metal_02_BrushedMetal_002_ChromeBrushed_Chrome
SubSubType
--------------
Id Name
-- ----------
1 001_BlueJeans_Denim
2 002_ChromeBrushed_Chrome
Type_SubType_SubSubType
-------------------------
TypeId SubTypeId SubSubType
------ --------- ----------
1 1 1
2 3 2
Now the trick part is to do a better normalization for the third level relation. It can be achieved if you add a identity column to the first relational table
So instead you can use this example:
Type_SubType
---------------------
Id TypeId SubTypeId
-- ------ ---------
1 1 1
2 1 2
3 2 3
4 2 4
and relating it to the second relational table
Type_SubType_SubSubType
-------------------------
Type_SubTypeId SubSubType
-------------- ----------
1 1
3 2
to retrieve only the possible matches is trivial
select * from type tp
join Type_SubType tp_sb on tp_sb.TypeId = tp.Id
join SubType sb on sb.Id = yb_sb.SubTypeId
or just (if you already selected a type and put it in the variable #TypeId)
Select * from SubType sb
join Type_SubType tp_sb on tp_sb.SubTypeId = sb.Id
where tp_sb.TypeId = #TypeId
and so on for SubSubTypes
note: this solutions only covers a fixed (or maxed) number of sub-sub. To get a total dynamic level of abstractions you ill need a recursive FK. Not something like rocket science but if you still the basics on SQL try stick with the most simple example.
I have table like this:
id products
------ ----------
5 1,2,3
6 2,4,5
9 1,4,7
17 4,6,7
18 1,6,8
19 2,3,6
I have to select only that rows, which row's products column contains one of (2,3) values.
In this case query must return:
id products
------ ----------
5 1,2,3
6 2,4,5
19 2,3,6
But I don't understand how to make construction of this query.
Any ideas?
Thanks in advance.
SELECT id,products
FROM yourTable
WHERE FIND_IN_SET('2',products)>0
OR FIND_IN_SET('3',products)>0
sqlFiddle
Would you mind to try this one please?
select * from TABLE_NAME where products regexp "(^|,)[23](,|$)";
Its doing either two or three at the begining, or at end. Or in between the commas.
Never, never, never store multiple values in one column.
Like you see now this will only give you headaches. Normalize your table. Then you can select normally.
Your table should look like this
id product
-- -------
5 1
5 2
5 3
6 2
6 4
6 5
...
With that table structure your select would be
select id
from your_normalized_table
where product in (2,3)
group by id
having count(distinct product) = 2
That query can make use of indexes and is really fast.