Creating new column based on condition from another table - mysql

As my previously written question was quite ambiguous and stupidly written, I will be more explicit in this thread. This is the previous post: How can I create a new column to SQL while adding conditions?
Basically, the two tables are these:
vw_RecipeIngredientCheck (https://i.stack.imgur.com/jlArc.png)
SELECT TOP (1000) [RecipeName]
,[RecipeIngredientName]
,[Unit]
,[Amount]
,[DisplayOrder]
,[IngredientGroup]
,[VirtualProductName]
FROM [dbo].[vw_RecipeIngredientCheck]
VirtualProduct (https://i.stack.imgur.com/xU8S7.png)
SELECT TOP (1000) [Id]
,[Name]
,[NativeUnitID]
,[Mapping]
,[Kg]
,[g]
,[l]
,[dl]
,[unit]
,[empty]
,[pack]
,[teaspoon]
,[spoon]
,[can]
,[bundle]
,[clove]
,[smidgen]
,[cube]
,[stick]
,[slice]
,[IsDurable]
,[letter]
,[Glass]
,[ProductImageId]
,[ResolvesToRealProduct]
FROM [dbo].[VirtualProduct]
My goal is to create a new column in the vw_RecipeIngredientCheck table which converts the Unit to a standard unit (which is given in the VirtualProduct table and is called NativeUnitID).
To be noted that the units in the VirtualProduct table already have the logic for converting implemented.
So, the point is to create a new column in vw_RecipeIngredientCheck and using the [VirtualProductName] to then multiply the [Amount] with the column from table VirtualProduct named after its [Unit].
Example:
[NewColumn] = [Amount] * (column name in VirtualProduct = [Unit])
Essentially, after joining the two tables I got this:
Joined tables
I don't know how to write the SQL Query so that the Amount gets multiplied by the column that matches its Unit. For example, in the image above, the row with Index 33 has the following:
NativeUnitID: 3 (which is Kg)
Unit: g
Amount: 250
In the column IngredientStd I would like to have the conversion of the current amount in grams into its NativeUnitID, which is Kg. Basically, the amount should be multiplied with the column "g", which is basically the content of the Unit column. What is troubling for me is comparing the values inside [Unit] with the name of the columns.

You have to try the dynamic table creation query to achieve this.
Reference: https://www.c-sharpcorner.com/blogs/creating-a-dynamic-table-in-sql-server1

I would change the table listing various weight units to a table with two data columns - name of unit and weight coefficient relative to most common unit (say 1 gramm). Then IMHO you could easily use two joins of tables by unit name, first converting to standard unit, then to your Native Unit. IMHO there is not much value in maintaining DB logic with names of units as names of columns. Maybe you really need it (or it is very convenient to use) for something else, then my advice is not applicable.

Related

How do I replace values in a column in KNIME?

I have a column of countries with 50 different values that I want to reduce to United States and Other.
Can someone help me with that?
Another example is Age which has 48 values that I'd like to reduce to only 4 like 1 to 18 = youth, 18-27 = starting, etc.
I've actually got about 5 columns that I want to reduce the values of. So would I need to repeat the process multiple times in KNIME or can I accomplish multiple column value replacements at once?
The latter on can easily be achieved with the Rule Engine
$Col0$ > 1 AND $Col0$ <18 => "youth"
For the First problem I'd use a String Replace (Dictionary).
I don't think you replace all at once but you can loop over columns.
For the second case I would use Numeric Binner:
For each column a number of intervals - known as bins - can be
defined. Each of these bins is given a unique name (for this column),
a defined range, and open or closed interval borders. They
automatically ensure that the ranges are defined in descending order
and that interval borders are consistent. In addition, each column is
either replaced with the binned, string-type column, or a new binned,
string-type column is appended.

SQL - How to select/delete rows with the max value depending on two others

I'm an intern in a property rental company. I'm in charge of developping the CRM under Symfony.
So, ones of my entities are properties (houses) and their availabilities. See the table structure below.
The problem I'm facing for now, is that the availabilities had been defined for each day (e.g. 28/01, 29/01, 30/01) instead of being defined for a range of day (e.g. 28/01 -> 30/01). So, the table is really heavy (~710 000 rows). Furthermore, before we changed the way of editing an availability, it created a new row for a same date instead of editing it. So, there are a lot of duplications in this table.
What I want, is to lighten the DB by keeping only the rows which have the max value in date_modif_availabilities for the same date_availabilities and id_properties.
For example, if I have these rows (availabilities_duplications):
I only want to keep the row with the latest modif like this (availabilities_keep_max_value) :
The thing is, I don't know enough the SQL language. I'm able to write few basics scripts but not complex subqueries. Even with code samples that I found.
Thank you in advance for your help.
You could select the elements for which no element with greater modified date exists.
Something like this:
SELECT avl1.*
FROM availabilities avl1
WHERE NOT EXISTS (SELECT *
FROM availabilities avl2
WHERE avl1.date_availabilities = avl2.date_availabilities
AND avl1.id_properties = avl2.id_properties
AND avl2.date_modif_availabilities > avl1.date_modif_availabilities);
This of course has the pre-condition that the combination of the three columns date_availabilities, id_properties and date_modif_availabilities is unique.
Furthermore, it seems that all columns (except the PK) may be NULL. Looks kinda odd to me.
You can use subquery :
select t.*
from table t
where id_availabilities = (select t1.id_availabilities
from table t1
where t1.id_properties = t.id_properties and
t1.date_availabilities = t.date_availabilities
order by t1.date_modif_availabilities desc
limit 1
);
However, if you have concern about the performance, then you want index on (id_properties, date_availabilities and id_availabilities).

MS Access - Update column in one table from another table based on values in a different column

One table (named Zip Table Definition) has 2-digit or 3-digit zips and their corresponding Market area(POD) with sample values as below:
Zip Market Area ID
350 AB_BIR
722 AR_LIT
850 AZ_PHO
T1 AB_CAL
Another table (named Test DB) has a field named Origin Zip with complete zipcodes (5-digit for US zips and 6-digit for Canada zips), and another field named Origin POD that will need to be updated from the first table. Basically we will need the first 3-digit of the full zipcode and then use that value to look up the corresponding Market Area ID from the first table. If it doesn't return a value, then we will extract the first 2-digit of the full zipcodes and do the lookup.
I tried to use an Update Query with DLOOKUP in the Update To row (for the first 3 digits scenario only, not sure how to handle the logic to opt for 2-digit if 3-digit doesn't return a value), but there seems to be something wrong with the query as the Run Query status bar fails to complete. Below is my query:
Field: Origin POD
Table: Test DB
Update To: DLookUp([Zip Table Definition].[Market Area ID],"Zip Table Definition",[Zip Table Definition].[Zip]=Left([Test DB].[Origin Zip],3))
I know it's much easier to handle it in Excel, but I wanted to learn how to use Access. Any insights and alternative solutions will be greatly appreciated.
Best regards.
If you really want to duplicate data into second table and use DLookup:
Update To: DLookUp("[Market Area ID]", "Zip Table Definition", "Zip='" & Left([Origin Zip], IIf(Len([Origin Zip])=5,3,2)) & "'")

concatenate using Allen Browne's example

I am using the 'concatenate related' module created by Allen Browne to concatenate rows into a single field. At first I had a lookup field at the table level and later realized this is not a good approach. So I deleted the lookup column and instead made a query for selecting values from the lookup table on my form and then store that value as a number in the table.
The module works when I concatenate the values but it is listing the number (id) whereas I would like the actual description (i.e. 1 = Red, 2 = Blue, etc.)
My SQL query code is as follows:
SELECT DISTINCT
tblCompany.JobID,
concatrelated("type","tblMonitor","JobID = " & [jobID]) AS Expr1
FROM tblCompany;
I would like "type" to display the description instead of the number. I know if I store my lookup value as text instead of number it will work. But for efficiency it seems the number should be stored in the table and then query for the description when you need it....or maybe text is fine??? I'm guessing I would need to add the lookup table to this query. I have tried but with no luck so far.
Create a query which joins tblMonitor with the table which holds the type description field. Then use that query with ConcatRelated.
ConcatRelated("type_descriptn","YourQuery","JobID = " & [jobID])

MYSQL search table, bit fields

I have a table with rows and where one field is a bit-value with 7 digits.
Suppose I have a procedure where I want to select all rows where this bit field equals '0101010', this is easily done by select * where .... and so on.
But: how do I do if I want to allow one/multiple digits of the digits to be either 1 Or 0, i.e I want to get all rows where the bitfield has an entry on the form 1001*1* where the * can be either 1 or 0. So, in this case I would like all entries where the bit field is 1001010, 1001011, 1001110 or 1001111.
select * from TABLE where bit_field in (1001010, 1001011, 1001110, 1001111) would probably work in this example, but if I want to use only the string '1001*1*' as input to the procedure, what then?
.
Any help is very appreciated.
Thanks,
Niklas
Edit: I've tried this: select * from table where field like bit'\\\0'; for getting all entries of the form **0, but that didn't work...
Edit2: It turned out it vas a bit-field, not binary... problem still remain though.
Not a direct answer to your question, per se', but an alternative approach. You mentioned that you didn't want to convert to individual columns because of legacy code. If you do want individual columns and the only thing holding you back is the legacy code, consider the following.
You could add columns for the options and use insert/update triggers to populate them OR you could create a view that splits the bits into separate columns. For new development, you can code to the new columns. Over time, as you modify legacy code you can change it to the new approach. When all the "read" legacy code has been changed, the last step is to change the "write" code to use the new columns rather than the bit column and remove the triggers.
I have a SQL Fiddle demonstrating this here. Note that I only included an insert trigger for brevity.