Fruits are running away ! Stored Procedure SQL? - sql

I have a table like this,
Table - Fruits
ID
Fruit_Truck_ID
Fruit_Crate_ID (can be null)
Mango (column exists but might get deleted) (these columnns are bit)
Apple
etc etc...
Now, what I want is that, create a stored procedure, which will either provide (truck id + fruit name) or provide (truck id + crate id + fruit name)
Fruit Columns can be added and deleted so I need to make a stored procedure which do following,
If in table, if fruit crate id is not null then select using truck id and crate id + given name of column, e.g. if I give this, GetFruitMango(truck_ID, Crate_ID, "Mango", it should return me the value of mango column which is bit (0 or 1)
Now if Crate_ID provided is not in table or is null then use truck_ID and Column name to get what's in mango column etc.

Related

Hive sql loop through table comparing values

I have a table in hive that looks like the below
fruit value
apple 2
apple 3
apple 4
plum 2
plum 3
plum 4
I want to loop through the table and compare the previous value and fruit and create a new column(total) based off of the loop. this would be the logic
if [fruit] = previous[fruit] then total = prev[fruit]
The new table should look like this
fruit value total
apple 2
apple 3 2
apple 4 3
plum 2
plum 3 2
plum 4 3
How can i achieve this using SQL in Hive?
Also i have ordered the results in my query so its grouped by fruit and ascending values
SQL tables represent unordered sets. There is no "previous" row unless a column specifies the ordering. Assuming you have such a column, then you can use lag():
select t.*,
lag(value) over (partition by fruit order by ?) as prev_value
from t;
The ? is for the name of the column that specifies the ordering.
Adding to the previous answer, you can artificially create an order by writing to a temp table like this:
create table #holding (rowid int identity, fruit varchar(max), value int)
insert #holding
select fruit, value from your table
order by fruit, value
This will recreate the order in the original table and allow you to do what Gordon said above

How Do I Count Occurrences in a Column in SQL?

I have a table that lists the following values. Some of the values in column 1 show up twice for the same customer (for example apple could show up 2 or more times.)
Column 1
Apples
Oranges
Bananas
I know I can use this to get the count for each of the values.
SELECT column 1, COUNT(*)
FROM table
GROUP BY column 1
Is there a way to write a SQL statement that looks at when the count of one of those values shows up twice for the same customer?
For example, I want to find out how many times apple shows up twice for the same customer.
Assuming you have a customer column, your query could look like this:
SELECT customer, column1, COUNT(*)
FROM table
GROUP BY customer, column1
HAVING COUNT(*) > 1;
This will show you a customer field, and your column1 (the column with Apple and Banana and so on), and the number of times the combination of these fields occur.
The GROUP BY will ensure that the count is calculated correctly.
The HAVING will only show records where the COUNT value is > 1 after the grouping has occurred.

union table, change serial primary key, postgresql

Postgresql:
I have two tables 'abc' and 'xyz' in postgresql. Both tables have same 'id' columns which type is 'serial primary key;'.
abc table id column values are 1,2,3 and also xyz id column containing same values 1,2,3,4
I want to union both tables with 'union all' constraint. But I want to change 'xyz' id column values to next value of 'abc' id column last value as 1,2,3,4,5,6,7
select id from abc
union all
select id from xyz
|id|
1
2
3
1
2
3
4
my wanted resuls as
|id|
1
2
3
4
5
6
7
BETTER - Thanks to #CaiusJard
This should do it for you
select id FROM abc
UNION ALL select x.id + a.maxid FROM xyz x,
(SELECT MAX(id) as maxid from abc) a
ORDER BY id
For anyone who's doing something like this:
I had a similar problem to this, I had table A and table B which had two different serials. My solution was to create a new table C which was identical to table B except it had an "oldid" column, and the id column was set to use the same sequence as table A. I then inserted all the data from table B into table C (putting the id in the oldid field). Once I fixed the refernces to point to from the oldid to the (new)id I was able to drop the oldid column.
In my case I needed to fix the old relations, and needed it to remain unique in the future (but I don't care that the ids from table A HAVE to all be before those from table C). Depending on what your trying to accomplish, this approach may be useful.
If anyone is going to use this approach, strictly speaking, there should be a trigger to prevent someone from manually setting an id in one table to match another. You should also alter the sequence to be owned by NONE so it's not dropped with table A, if table A is ever dropped.

Updating Relational Tables using merge

In a hypothetical example, say I have two tables: FARM and FRUIT
FARM is organized like:
FARM_ID Size
1 50
2 100
3 200
...
and FRUIT is organized like:
Reference_ID FRUIT
1 Banana
1 Grape
1 Orange
2 Banana
2 Strawberry
FRUIT table is created from taking a parameter #fruit from excel which is a delimited string using '/'.
For example, #fruit = 'Banana/Grape/Orange'
And using a statement like:
INSERT INTO FRUIT(
Fruit,
Reference_ID,
)
SELECT Fruit, Scope_IDENTITY() from split_string(#fruit, '/')
Where split_string is a function.
My goal is to check for updates. I want to take in a Farm_ID and #fruit and check to see if any changes have been made to the fruit.
1) If the values haven't changed, dont do anything
2) If a new fruit was added, add it to the FRUIT table with the farm_ID
3) If there is a fruit in the FRUIT table that does not correspond to the new delimited list for the respectful FARM_ID, remove it from the FRUIT table.
I think a Merge statement would probably work but open to suggestions. Let me know if anything is unclear. Thank you
EDIT
Im fairly new to SQL but have tried using a merge...
Declare #foo tinyint
Merge Fruit as Target
Using (Select Fruit , #workingID From split_string(#fruit, '/') As source (fruit, ID)
--#workingID is just a way to get the ID from other parts of the sproc.
ON (TARGET.fruit = source.fruit)
WHEN MATCHED THEN
SET #foo = 1
WHEN NOT MATCHED
THEN DELETE
WHEN NOT MATCHED THEN
INSERT INTO FRUIT(
Reference_ID,
Fruit
)
VALUES(
Then I am a bit stuck on how to get unique, new values
Any way your input contains the new fruit list against the farm id. So better option is to delete the existing and insert the new list of fruit against the farmid.
Sample script is given below.
--loading the input to temp table
SELECT Fruit,#referenceid ReferenceId -- farmid corresponding tithe fruit list
INTO #temp
FROM Split_string(#fruit,'/')
-- delete the existing data against the given farmid
DELETE FROM fruit f
WHERE EXISTS ( SELECT 1 FROM #temp t
WHERE f.Reference_id=t.ReferenceId)
-- insert the new list
INSERT INTO fruit
SELECT fruit,referenceId
FROM #temp

Need SQL to Sort table based on another list of array

I need to get list of item from my table but in sorted order and list must be sorted as below:
Assume I have fields named as "productid" and "productname" and table as below records
1. milk
2. pizza
3. boll
And I have another list in array such as
boll
pizza
milk
Now I want to sort table list based on array value and get below list"
3. boll
2. pizza
1. mike
Is there any SQL which can do what I need? Or I need to do it manually via coding.
You can do this if with the following bit of pseudo code, from your application code
sqlexecuter.run(
"CREATE TEMPORARY TABLE ORDERED_ENTRIES(
ORDER_ENTRY NOT NULL AUTO_INCREMENT PRIMARY KEY,
PRODUCT_NAME varchar(255) --Put the same amount size as your other table
)")
Then in your code insert them into that table, in a similar way to this
for(i:lenght(myProductArray))
sqlexecuter.run
("
INSERT INTO ORDERED_ENTRIES
VALUES("+myProductArray[i]+")"
)
And then select like this
sqlexecuter.select(
"
SELECT OE.ORDER_ENTRY, PT.PRODUCT_NAME
FROM PRODUCT_TABLE AS PT, ORDERED_ENTRIES AS OE
WHERE
OE.PRODUCT_NAME = PT.PRODUCT_NAME
ORDER BY OE.ORDER_ENTRY
");