Summing-up For an Arbitrary List of Rows - mysql

I wish I could write something like this:
SELECT sum(weight) FROM items WHERE itemID IN (4217,4575,6549,4217)
where itemID is the primary key, and SQLite and MySQL would process it as expected, i.e. add the 4217-th row to the sum twice, but they don't.
is there something at least in MySQL I'm not aware of that's intended for cases like this? if not, what would a workaround be like? any row can have any number of duplicates in the list. the list can be big although in most cases is small.

I don't know any out of the box functionality that can do this. Here is the workaroud. You can insert those values into temp table and use a join:
CREATE TEMPORARY TABLE List(ID INT);
INSERT INTO List(ID) VALUES(4217),(4575),(6549),(4217);
SELECT SUM(i.weight)
FROM items i
JOIN List l ON i.itemID = l.ID;

Related

Is there way to add multiple values to 1 ID in access

I have a table that has Act ID, and another table that has Act ID, percentage complete. This can have multiple entries for different days. I need the sum of the percentage added for the Act ID on the first tableZA.108381.080
First table
Act ID Percent Date
ZA.108381.110 Total from 2 table
ZA.108381.120
ZA.108476.020
ZA.108381.110 25% 5/25/19
ZA.108381.110 75 6/1/19
ZA.108381.120
ZA.108476.020
This would be generally considering not good practice. Your primary key should be uniquely identifiable for that specific table, and any other data related to that key should be stored in separate columns.
However since an answer is not a place for a lecture, if you want to store multiple values in you Act ID column, I would suggest changing your primary key to something more generic "RowID". Then using vba to insert multiple values into this field.
However changing the primary key late in a databases life may cause alot of issues or be difficult. So good luck
Storing calculated values in a table has the disadvantage that these entries may become outdated as the other table is updated. It is preferable to query the tables on the fly to always get uptodate results
SELECT A.ActID, SUM(B.Percentage) AS SumPercent
FROM
table1 A
LEFT JOIN table2 B
ON A.ActID = B.ActID
GROUP BY A.ActID
ORDER BY A.ActID
This query allows you to add additional columns from the first table. If you only need the ActID from table 1, then you can simplify the query, and instead take it from table 2:
SELECT ActID, SUM(Percentage) AS SumPercent
FROM table2
GROUP BY ActID
ORDER BY ActID
If you have spaces other other special characters in a column or table name, you must escape it with []. E.g. [Act ID].
Do not change the IDs in the table. If you want to have the result displayed as the ID merged with the sum, change the query to
SELECT A.ActID & "." & Format(SUM(B.Percentage), "0.000") AS Result
FROM ...
See also: SQL GROUP BY Statement (w3schools)

Subquery results more than one values

I have two tables:
table_people
col_name
col_sex
table_gender
col_male
col_female
Suppose the table_people consist three rows, (a,'M'),(b,'M'),(c,'F').
Now I need a query(subquery) to insert this first table value in second table as:
(a,c),(b,'').
If it is possible in mysql?
You table structure is bad.
My suggestion is to drop table_gender because it doesn't make sense at all. You already have a list of person with gender on table table_people.
You can generate a VIEW, if you want to list the gender separately.
CREATE VIEW MaleList
AS
SELECT col_name
FROM table_people
WHERE col_sex = 'M'
and another view for list of females only.
CREATE VIEW FemaleList
AS
SELECT col_name
FROM   table_people
WHERE  col_sex = 'F'
First of all the table structure is bad. I dont see a point of saving M or F in another table when you col_sex in your table_people. Still if you want to do it, first you have to specify a foreign key connecting the two tables.

SQL deduping help?

I'm sure there are a ton of ways to do this, but right now I'm struggling to find the way that will work properly given the data.
I basically have a table containing duplicates which have additional fields tied to them and source details that take priority over others. So basically I added a "priority" field to my table which I then updated based on source priority. I now need to select the distinct records to populate my "unique" records table (which I'll then apply unique key constraint to prevent this from happening again on the field required!)....
So I have basically, something like this:
Select phone, carrier, src, priority
from dbo.mytable
So basically I need to pull distinct on phone in order of priority (1,2,3,4, etc), and basically pull the rest of the other data along with it and still keep UNIQUE on phone.
I've tried a few things using sub-select from the same table with min(priority) value, but outcome still doesn't seem to make sense. Any help would be greatly appreciated. Thanks!
EDIT I need to dedupe from the same table, but I can populate a new table with the uniques if needed based on my select statement to pull the uniques. This is in MSSQL, but figured anyone with SQL knowledge could answer.
For example, let's say I have the following rows:
5556667777, ATT, source1, 1
5556667777, ATT, source2, 2
5556667777, ATT, source3, 3
I need to pull uniques based on priority 1 first..... the problem is, I need to remove any all other dupes from the table based on the priority order without ending up with the same phone number twice again. Make sense?
So you're saying the combination (phone, priority) is unique in the existing table, and you want to select the rows for which the priority is smallest?
SELECT mytable.phone, mytable.carrier, mytable.src
FROM mytable
INNER JOIN (
SELECT phone, MIN(priority) AS minpriority
FROM mytable
GROUP BY phone
) AS minphone
ON mytable.phone = minphone.phone
AND mytable.priority = minphone.minpriority

How do I make the rows of a lookup table into the columns of a query?

I have three tables: students, interests, and interest_lookup.
Students has the cols student_id and name.
Interests has the cols interest_id and interest_name.
Interest_lookup has the cols student_id and interest_id.
To find out what interests a student has I do
select interests.interest_name from `students`
inner join `interest_lookup`
on interest_lookup.student_id = students.student_id
inner join `interests`
on interests.interest_id = interest_lookup.interest_id
What I want to do is get a result set like
student_id | students.name | interest_a | interest_b | ...
where the column name 'interest_a' is a value in interests.name and
the interest_ columns are 0 or 1 such that the value is 1 when
there is a record in interest_lookup for the given
student_id and interest_id and 0 when there is not.
Each entry in the interests table must appear as a column name.
I can do this with subselects (which is super slow) or by making a bunch of joins, but both of these really require that I first select all the records from interests and write out a dynamic query.
You're doing an operation called a pivot. #Slider345 linked to (prior to editing his answer) another SO post about doing it in Microsoft SQL Server. Microsoft has its own special syntax to do this, but MySQL does not.
You can do something like this:
SELECT s.student_id, s.name,
SUM(i.name = 'a') AS interest_a,
SUM(i.name = 'b') AS interest_b,
SUM(i.name = 'c') AS interest_c
FROM students s
INNER JOIN interest_lookup l USING (student_id)
INNER JOIN interests i USING (interest_id)
GROUP BY s.student_id;
What you cannot do, in MySQL or Microsoft or anything else, is automatically populate columns so that the presence of data expands the number of columns.
Columns of an SQL query must be fixed and hard-coded at the time you prepare the query.
If you don't know the list of interests at the time you code the query, or you need it to adapt to changing lists of interest, you'll have to fetch the interests as rows and post-process these rows in your application.
What your trying to do sounds like a pivot.
Most solutions seem to revolve around one of the following approaches:
Creating a dynamic query, as in Is there a way to pivot rows to columns in MySQL without using CASE?
Selecting all the attribute columns, as in How to pivot a MySQL entity-attribute-value schema
Or, identifying the columns and using either a CASE statement or a user defined function as in pivot in mysql queries
I don't think this is possible. Actually I think this is just a matter of data representatioin. I would try to use a component to display the data that would allow me to pivot the data (for instance, the same way you do on excel, open office's calc, etc).
To take it one step further, you should think again why you need this and probably try to solve it in the application not in the database.
I know this doesn't help much but it's the best I can think of :(

MYSQL - Help with a more complicated Query

I have two tables:
tbl_lists and tbl_houses
Inside tbl_lists I have a field called HousesList - it contains the ID's for several houses in the following format:
1# 2# 4# 51# 3#
I need to be able to select the mysql fields from tbl_houses WHERE ID = any of those ID's in the list.
More specifically, I need to SELECT SUM(tbl_houses.HouseValue) WHERE tbl_houses.ID IN tbl_lists.HousesList -- and I want to do this select to return the SUM for several rows in tbl_lists.
Anyone can help ?
I'm thinking of how I can do this in a SINGLE query since I don't want to do any mysql loops (within PHP).
If your schema is really fixed, I'd do two queries:
SELECT HousesList FROM tbl_lists WHERE ... (your conditions)
In PHP, split the lists and create one array $houseIDs of IDs. Then run a second query:
SELECT SUM(HouseValue) FROM tbl-Houses WHERE ID IN (.join(", ", $houseIDs).)
I still suggest changing the schema into something like this:
CREATE TABLE tbl_lists (listID int primary key, ...)
CREATE TABLE tbl_lists_houses (listID int, houseID int)
CREATE TABLE tbl_houses (houseID int primary key, ...)
Then the query becomes trivial:
SELECT SUM(h.HouseValue) FROM tbl_houses AS h, tbl_lists AS l, tbl_lists_houses AS lh WHERE l.listID = <your value> AND lh.listID = l.listID AND lh.houseID = h.houseID
Storing lists in a single field really prevents you from doing anything useful with them in the database, and you'll be going back and forth between PHP and the database for everything. Also (no offense intended), "my project is highly dynamic" might be a bad excuse for "I have no requirements or design yet".
normalise http://en.wikipedia.org/wiki/Database_normalization