single (unique) results in sql query result - mysql

I'm really stuck:
A little background: I've build a website with a database with multiple tables.
It is about minerals that have fluorescense under different types of UV light (long wave, medium wave and short wave, LW, MW and SW)
The website is working fine, however, with a little bit too much results.
I have a table with all the details of the minierals, I have a table where I put the photo's and with those photo's I save what kind of UV is used.
Now I want a query that filters for specific wave lengts; but I get double results since I've multiple photo's with a specific wave length, see yellow marking in example. 19 results instead of 18 results
How do I get the distinct results? So, in this case, how do I get 18 unique results instead of 19 results as shown?
The query I use right now is
SELECT m.korte_naam, m.url_naam, m.mineraal_id, m.opmerking, m.vindplaats_kort, m.gewicht from `mineraal` m, `foto` f where m.mineraal_id = f.mineraal_id and f.lichtbron = 'SW';
Any help is highly appreciated!

If you only want to select each item once, you can use:
SELECT DISTINCT m.korte_naam, m.url_naam, m.mineraal_id, m.opmerking, m.vindplaats_kort, m.gewicht from `mineraal` m, `foto` f where m.mineraal_id = f.mineraal_id and f.lichtbron = 'SW';
If you want not to keep the same record more than once, you need to check before insertion that record hadn't been inserted already.

Related

Transforming Results from Rows into Columns

I have a data set that contains both common and unique values, which I am attempting to return in a useable format to allow further analyse/work to be taken based on said results.
The desired result would be to have a script that would recognise the common values such as mpan/serial_number/read_at so as to only return a single row, but also to recognise the unique values those being the read_at and identifier.
Currently my script returns a unique row based on the identifier and the value, but I would like to be able to return a unique row for the read_at date for as many identifiers and values as are held. In most cases there are only two identifiers and values, but there could be as many as five.
The issue I have is that when I try to make distinct work, it will only then return the first found result, where I am expecting a pair of results at minimum. I am also unclear as to how I could stop getting a new row and instead create the result as an additional column?
My base script which pulls everything is as below, I have tried a few variances on this, but think this would likely be the best place to start from with regards to any help you may be able to offer?
SELECT *
FROM consumer.stg_d0010_v2_026_027
/*LEFT JOIN consumer.stg_d0010_v2_026_028_029
ON consumer.stg_d0010_v2_026_028_029.file_identifier = consumer.stg_d0010_v2_026_027.file_identifier
AND consumer.stg_d0010_v2_026_028_029.mpan = consumer.stg_d0010_v2_026_027.mpan*/
LEFT JOIN consumer.stg_d0010_v2_026_028_030_032
ON consumer.stg_d0010_v2_026_028_030_032.file_identifier = consumer.stg_d0010_v2_026_027.file_identifier
AND consumer.stg_d0010_v2_026_028_030_032.mpan = consumer.stg_d0010_v2_026_027.mpan
LEFT JOIN consumer.stg_d0010_v2_026_028_030_033
ON consumer.stg_d0010_v2_026_028_030_033.file_identifier = consumer.stg_d0010_v2_026_027.file_identifier
AND consumer.stg_d0010_v2_026_028_030_033.mpan = consumer.stg_d0010_v2_026_027.mpan
where consumer.stg_d0010_v2_026_028_030_032.read_At > '2022-10-01'
and consumer.stg_d0010_v2_026_027.mpan in (
)
Example dataset in image below.
enter image description here
And desired outcome
enter image description here
The issue I have is that when I try to make distinct work, it will only then return the first found result, where I am expecting a pair of results at minimum. I am also unclear as to how I could stop getting a new row and instead create the result as an additional column?

MySQL combine columns from two separate and complex queries into one row

I’m working on a website where there are many distinct lines of garments. A line is defined as garments of the same design, style, manufacturer etc. Within a line, garments come in different sizes and colours.
To compose a chart of all the colours available in one particular line the following query works fine (I’m working in Coldfusion but PHP would use the same query).
SELECT
skuColourwayID,cHex,cLongName,skuID, cwColID1
from garment_sku
join garment_colourways
on cwID=skuColourwayID
join garment_colour_name
on cID=cwColID1
where skuLineID= <cfqueryPARAM value = "#url.lnID#" CFSQLType = "CF_SQL_INTEGER">
group by skuColourwayID
In order to accumulate all the info I need, I have to access three tables using joins. (I don’t have any choice about how the data is presented to me). The line is identified by lnID which in the above case starts as a url variable. Starting with the sku table (garment_sku) I access the colourways table (garment_colourways) and get the colourway colour id (cwColID1). By applying this to the colour name table (garment_colour_name) I can get the actual name of the colour, and it’s hex value.
This all works perfectly, EXCEPT a few garments come in bi-colours (ie different colour sleeves to body or collar etc). There is a second column in the garment_sku table, cwColID2 which denotes the second colour.
One way around this would be to perform two separate queries, where cwColID1 is replaced by cwColID2 in the second query. I could then combine the queries programatically to achive the bi-colour where required. However, this seems rather inelegant and I’m sure MySQL has a way of dealing with this in one query?
I hate to say it but there is also provison in the tables for a third colourway cwColID3 though I’ve never come across any three colour garments and would be very happy to solve this for just the two colours.
Thanks for any help you can give.
You just need to JOIN to the garment_colour_name table a second time to get the name of the second colour. Note that since not all garments will have 2 colours, you need to use a LEFT JOIN rather than an INNER JOIN:
SELECT
skuColourwayID,
gc1.cHex AS c1Hex,
gc1.cLongName AS c1Name,
gc2.cHex AS c2Hex,
gc2.cLongName AS c2Name,
skuID,
cwColID1,
cwColID2
from garment_sku
join garment_colourways
on cwID=skuColourwayID
join garment_colour_name gc1
on gc1.cID=cwColID1
left join garment_colour_name gc2
on gc2.cID=cwColID2
where skuLineID= <cfqueryPARAM value = "#url.lnID#" CFSQLType = "CF_SQL_INTEGER">
group by skuColourwayID

Testing if a row exists in a table for a report

I'm trying to write a report that lists all the rows from a master table and inserts a field ("Y"/"N") if the key exists in a current-use table. For example, the COLOR_MASTER table has 256 colors by COLOR_NAME (field/key). The CURRENT_PROJECTS has a row for each project and the COLOR_NAME (field). I want to list all the COLOR_MASTER rows and then on the same print line a "Y" or "N" if that COLOR_NAME is used in the CURRENT_PROJECTS table.
I've tried to mess around with it in the Design View and have had no luck. The JOIN that was created looks basically like this and how I want the report is following the dashes:
RIGHT JOIN COLOR_MASTER ON CURRENT_PROJECTS.COLOR_NAME =
COLOR_MASTER.COLOR_NAME ON CURRENT_PROJECTS.COLOR_NAME =
COLOR_MASTER.COLOR_NAME;
--------
Color Used
BLUE
RED Y
YELLOW
I have no expertise in JOINs and I don't understand why this JOIN was created or what I need to do to fix it. Based on my reading, I guess it's trying to do an outer join.
Currently, I'm just trying to show the COLOR_NAME if used as I don't know how to test that it is used and convert it to "Y". I don't care if the color is used once or twenty times and I don't really want any data from the CURRENT_PROJECTS table.
Under the "Used" column I now have "#Error" on all lines. So, I'm figuring that the RIGHT JOIN has an error.
Any guidance is appreciated.
Thanks
I expect the RIGHT JOIN is defined in the table Relationships builder and a query using the tables adopts the established link. If you want to change the join type in a query then with query in design view, double click on the line linking tables to open the Join Properties dialog.
If there is only one record per project in Current_Projects and a color can be used only once, simply:
SELECT Color_Master.Color_Name, IIf([Current_Projects].[Color_Name] Is Null,"N","Y") AS Used
FROM Color_Master LEFT JOIN Current_Projects ON Color_Master.Color_Name = Current_Projects.Color_Name;
However, it sounds like each color can be used for multiple projects. So will need to use GROUP BY or DISTINCT query joined to the Master_Colors table:
SELECT DISTINCT Current_Projects.Color_Name FROM Current_Projects;
SELECT Color_Master.Color_Name, IIf([Query1].[Color_Name] Is Null,"N","Y") AS Used
FROM Query1 RIGHT JOIN Color_Master ON Query1.Color_Name = Color_Master.Color_Name;
Here is all-in-one SQL:
SELECT Color_Master.Color_Name, IIf([Query1].[Color_Name] Is Null,"N","Y") AS Used
FROM (SELECT DISTINCT Current_Projects.Color_Name FROM Current_Projects) AS Query1
RIGHT JOIN Color_Master ON Query1.Color_Name = Color_Master.Color_Name;
If you don't want anything displayed for the N result then use Null without quote marks in the expression.
An alternative is DLookup() but domain aggregate functions can perform slowly in query or textbox expression.
Advise not to save the calculated value to table, just calculate when needed.
You don't have to do it all in one query. Start by building a query that as the IDs of all the colors currently in use. Name it something like ColorsInUse and save it.
It could be something as simple as:
SELECT [COLOR_NAME] FROM [CURRENT_PROJECTS] GROUP BY [COLOR_NAME]
Then all you have to do is run the following queries:
UPDATE [COLOR_MASTER] SET [MyField]="N"
UPDATE [COLOR_MASTER] SET [MyField]="Y" WHERE [COLOR_NAME] IN [ColorsInUse]
Another way of doing it is by using DLookup. Something like this:
UPDATE [COLOR_MASTER] SET [MyField]=IIF(NZ(DLookup("[COLOR_NAME]","[CURRENT_PROJECTS]","[COLOR_NAME]='" & [COLOR_NAME] & "'"),"")="","N","Y")
Some notes: You should not use a text field (like a name) as your key. You should always use numerical IDs. You should also never use a text Y/N. Use an actual Yes/No field instead.

SQL SUM condition on each column

I'm giving my best efforts to write a query to get the desired output format shown the second table here. Is there a better way to achieve this, table 1 has the raw data and I want to find the sum of monthly usage of unique devices for a given user. Any help is really appreciated.
table format
Apologize for not being clear in first place. tagged different image to illustrate better. If you look at this data in new image attached. After I filter by username - I get that data output. My need is to get the sum of usage by month by device.
Ex: rows highlighted in the image, where iPhone-6sPlus is used multiple times each month across months. I'm looking for a query that gives output as
iPhone-6SPlus is used xx_hrs in Jan, yy_hrs in feb so on. Similarly for other device models. Hope this helps. Thanks.
Better image
create table #product (model varchar(50),users varchar(5), monthofuse Varchar(3),yearofuse int,usage int)
Insert into #product values('X','a', 'JAN',2010,34), ('X','a', 'Feb',2010,20),('X','a', 'Mar',2010,10),('Y','a', 'Jan',2010,30),
('Y','b', 'Jan',2010,30),('Y','b', 'Feb',2010,30),('X','a', 'JAN',2011,50)
select * from #product
Select * FROM
(Select users,monthofuse,usage,model from #product) q
Pivot
(
sum(usage) for q.monthofuse in([JAN],[FEB],[MAR],[APR],[MAY],[JUN],[JUL],[AUG],[SEP],[OCT],[NOV],[DEC]))As pvttable

How to classify ranges of values in access query

Hello I am currently stuck on a problem. Any help will be appreciated. The data I am looking to classify are weights ranging from 0-80. If the line item is between 0-19 tag it as light 19-39 medium, etc... I am struggling for a starting point for how to get this to work. This query is pulling multiple fields from the data source but this is the only one that is being modified. After this the data will be re-classified based on light, medium, etc.
Thanks for the help. Let me know if anything is needed
You can make a table called WeightClasses
Then you can join to this
Select t.*, wc.weightclassname
From Things as t
inner join WeightClasses as wc
on t.Weight >= wc.LowerBound and t.Weight < wc.UpperBound
This will produce results like this
I think this is a lot easier to read and auditable than IIF statements. You can change your classifications in a table without changing code and you can make sense of your classes very quickly and easily by looking at the table. You can also add weight classes just by adding new records.
USE IIF like this:
IIF(SteelData.[Unit Weight]<19.0001,'Light',IIF(SteelData.[Unit Weight] <
39.00001,'Medium',IIF([etc.])))