Mysql -- how to retrieve NVP values and group them? - mysql

Lets say we have this MySQL table
name value
author Sabriel Armstrong
author Peter Abhorsen
author Garth Stein
item bell
item book
item sword
item wand
Given these database entries, is there a way to retrieve this values as to get it in the format below? Or is my database modeling wrong?
array(
[author] => array(Sabriel Armstrong,Peter Abhorsen, Garth Stein),
[item] => array(bell,book,sword, wand)
)

MySQL does not have arrays so it's hard to figure out what exact result set you are expecting. In any case, your DB design provides no way to match an author with an item: such information is simply not stored anywhere.
I suppose you'll have a reason to avoid this:
author item
====== ======
Sabriel Armstrong bell
Peter Abhorsen book
:-?

Related

How to find missing numbers within a column of strings

I'm trying to find unaccounted for numbers within a substantially large SQL dataset and facing some difficulty sorting.
By default the data for column reads
'Brochure1: Brochure2: Brochure3:...Brochure(k-1): Brochure(k):'
where k stands in for the number of brochures a unique id is eligible for.
Now the issue arises as the brochures are accounted for a sample updated data would read
'Brochure1: 00001 Brochure2: 00002 Brochure3: 00003....'
How does one query out the missing numbers, if in the range of number of say 00001-88888 some haven't been accounted next to Brochure(X):
The right way:
You should change the structure of your database. If you care about performance, you should follow the good practices of relational databases, so as first comment under your question said: normalize. Instead of placing information about brochures in one column of the table, it's much faster and more clear solution to create another table, that will describe relations between brochures and your-first-table-name
<your-first-table-name>_id | brochure_id
----------------------------+---------------
1 | 00002
1 | 00038
1 | 00281
2 | 28192
2 | 00293
... | ...
Not mention, if possible - you should treat brochure_id as integer, so using 12 instead of 0012.
The difference here is, that now you can make efficient and simple queries, to find out how many brochures one ID from your first table has, or what ID any brochure belongs to. If for some reason you need to keep the ordinal number of every single brochure you can add a column to the above table, like brochure_number.
What you want to achieve (not recommended): I think the fastest way to achieve your objective without changing the db structure, is to get the value of your brochures column, and then process it with your script. You really don't want to create a SQL statement to parse this kind of data. In PHP that wolud look something like this:
// Let's assume you already have your `brochures` column value in variable $brochures
$bs = str_replace(": ", ":", $brochures);
$bs = explode(" ", $bs);
$brochures = array();
foreach($bs as $b)
$brochures[substr($b, 8, 1)] = substr($b, strpos($b, ":")+1, 5);
// Now you have $brochures array with keys representing the brochure number,
// and values representing the ID of brochure.
if(isset($brochures['3'])){
// that row has a defined Brochure3
}else{
// ...
}

Rails, MySql, JSON column which stores array of UUIDs - Need to do exact match

I have a model called lists, which has a column called item_ids. item_ids is a JSON column (MySQL) and the column contains array of UUIDs, each referring to one item.
Now when someone creates a new list, I need to search whether there is an existing list with same set of UUIDs, and I want to do this search using query itself for faster response. Also use ActiveRecord querying as much as possible.
How do i achieve this?
item_ids = ["11E85378-CFE8-39F8-89DC-7086913CFD4B", "11E85354-304C-0664-9E81-0A281BE2CA42"]
v = List.new(item_ids: item_ids)
v.save!
Now, how do I check whether a list exists which has item ids exactly matches with that mentioned in query ? Following wont work.
list_count = List.where(item_ids: item_ids).count
Edit 1
List.where("JSON_CONTAINS(item_ids, ?) ", item_ids.to_json).count
This statement works, but it counts even if only one of the item matches. Looking for exact number of items.
Edit 2
List.where("JSON_CONTAINS( item_ids, ?) and JSON_LENGTH(item_ids) = ?", item_ids.to_json, item_ids.size).count
Looks like this is working
You can implement a has many relation between lists and items and then access like this.
List.includes(:item).where('items.id in (?)',item_ids)
To implement has_many relation:
http://guides.rubyonrails.org/association_basics.html#the-has-many-through-association

How to add selected item into mysql database Laravel Schema Builder?

I used webpatser/laravel-countries
in my controlleer
$countries= DB::table('countries')->lists('name');
to select country list in my form i got all the country
{!! Form::select('country',$countries,null) !!}
in my schema now i have like this
$table->string('country');
i can select the country but when i submit country column blank. any idea ?
Edit 2:
Your insert need to look like this:
DB::table('users')->insert(
['country' => 'Canada']
);
https://laravel.com/docs/5.2/queries#inserts
Edit: if you want to submit the string of the country name then you need the string to be the key in your array. Like this:
$countries= DB::table('countries')->lists('name', 'name');
That's not typical use of a database relationship though. I'd expect the user table to have a country_id integer field that matches the id field in countries. That's what my original answer (below) covers.
Original:
You'll want the id in your $countries array. I bet right now your ids are off by one, starting at 0 instead of 1 like in your DB.
$countries= DB::table('countries')->lists('name', 'id');
There are different ways to save relations in laravel, but I actually prefer to skip that when possible and save directly to the country_id field.
{!! Form::select('country_id',$countries,null) !!}
But that depends on how your relationship is setup. And how you're saving. Show all the code!

SQL To Pull Linked List(ish) Data From Tables

Thank you in advance for your help...
I want to get the parent site list/informatoin for a site based on its ID. There is a site hierarchy described in 2 tables, like this:
table: site
- id (PK)
- name
table: hierarchy
- siteid (PK) (siteid => site.id)
- parented (PK) (parented => site.id)
- topid (topid => site.id)
For example, you may have the following data in the tables:
site:
id,name
0,Earth
1,US
2,NY
3,GA
4,Queens
5,Farmers' Market
6,Buckhead
hierarchy:
siteid,parented,topid
5,4,1
4,2,1
2,1,1
1,0,1
5,6,1
6,3,1
3,1,1
1,0,1
I want to get all the parents of the Farmers's Market sites. There are markets in both Buckhead and Queens.
How do I make SQL walk / recurse up the tree to get something like this if I want the parent list for site id=5?:
site_name,parent_name
Farmers' Market,Queens
Queens,NY
NY,Earth
Farmers' Market,Buckhead
Buckhead,GA
GA,Earth
It occurs to me that there may need to be more than one row in the site table for Farmers' Market, but, I don't think so...
Thanks for your help,
David

USING PDO & MYSQL to get rows compared and switched to columns

I have a Products table, an Imprint table, a Manufacturer table and an ingredients table - along with other tables.
I am currently generating information and use what is called "file_name" as the id (it is a FDA assigned 36-40 digit id that goes with each product). What is happening now is people enter of few letters and the autocomplete dropdown provides the exact spelling. When they click SUBMIT and it brings up all entries that match. If they select a generic product it also includes the "brand" product - if they enter a brand it also includes the generic.
The current display is as follows:
Sold by: Sold using Available Chemical name Data based
name Since: on company
report submitted:
C----- Health Lortab 2011-01-13 Hydrocodone Bitartrate etc 2010-12-07
R—Distributors Hydrocodone 2010-02-18 Hydrocodone Bitartrate etc 2009-12-17
Bitartrate
And Acetaminophen
C-- Health Vicodin 1983-01-07 Hydrocodone Bitartrate etc 2009-11-03
R—Distributors Hydrocodone 2010-07-30 Hydrocodone Bitartrate etc 2010-12-28
Bitartrate
And Acetaminophen
This is working fine. I will be adding a check box on the left which will allow up to 3 of the products to be chosen for comparison and additional information.
THE NEXT STEP:
After they check 1, 2 or 3 items, I want to display like this:
"ALL of the versions of the product you checked contain the following ingredients:"
(Those ingredients common to all chosen products).
ACETAMINOPHEN, CELLULOSE, CORN, CROSPOVIDONE, HYDROCODONE BITARTRATE, MICROCRYSTALLINE, STARCH and STEARIC ACID
(Show the ingredients in each product NOT held in common by all.
End result in COLUMNS)
“IN addition, EACH of the products you chose have the following ingredients:"
COLUMN 1(Product 1) COLUMN 2 (Product 2) COLUMN 3 ( Product 3)
COPOVIDONE MAGNESIUM STEARATE CROSCARMELLOSE SODIUM
CROSCARMELLOSE SODIUM POVIDONE D&C YELLOW NO. 10
D&C RED NO. 27 SILICON DIOXIDE FD&C BLUE NO. 1
D&C RED NO. 30 POVIDONE
HYDRATED SILICA SILICON DIOXIDE
MAGNESIUM STEARATE SUCROSE
End of display
Ingredient table: there are 20,000 rows,46 columns. Each row is a different drug and contains the id, file-name and then the ingredients, Each drug (row) has a different combination and number of ingredients. Unused fields are marked "Null";:
Ingredient columns in each row:
id, file_name, 0_gred, 1_gred, 2_gred, 3_gred, 4_gred, 5_gred, 6_gred, 7_gred, 8_gred, 9_gred, 10_gred, 11_gred, 12_gred, 13_gred, 14_gred, 15_gred, 16_gred, 17_gred, 18_gred, 19_gred, 20_gred (etc. up to 43_gred)
The question is how and what approach to use to get the format I need for the ingredients. I have experience in developing registration systems, I am fairly knowledgeable in PHP and am starting to get use to PDO. My Sql experience is minimal and is basically on a "need to know" basis.
I have wondered whether I should focus on a monster of a MySQL query or more on the php side. I thought about a query giving the ingredients common to all 3 and then subtracting that result from each individual drug list to get Part II but that appears to be quite advanced mysql – especially since I need the data to switch from row to COLUMN layout. Any help?
Another idea was to do a query that concatenated the ingredients of each row and then doing array procedures on the php side. Problems, I am having a hard time finding the right code to pull the ingredients out of each row since the number of “NULL” fields compared to “used” fields varies with each row. (How to count null COLUMNS in PDO query? I’ve tried and get the full count of columns in the table.)
To me, this is a braintwister with several steps. I’m looking for the “magic” MySql Code (if it exists) and or suggestions as to what approach (using php, mysql, PDO) you would pursue.
Your interest/help is appreciated!!
Laura
I figured out a php way to do what I needed. I'm sure there is a faster MySql way. If you know of one please share! Laura
First, I set the Mysql empty values to default to "no_ingre".
Then I did the following code 3 times for the 3 choices:
SELECT 'all the ingredient fields WHERE id=$name_of_id'
$result=$stmt->fetch(PDO::FETCH_ASSOC);
foreach($result as $key => $value) {
if ($value == "no_ingre") unset($result[$key]);
}
FIND THE ingredients COMMON TO ALL:
$same_detect= array_intersect($result, $result2, $result3);
$p_same=(implode(", ", $same_detect));
echo "<br />The below ingredients are in all of the chosen products<br />";
echo $p_same;
To FIND THE ONES NOT COMMON TO ALL: Do the below code 3 times (for each ingredient array):
foreach ($result as $item) {
if (!in_array($item, $same_detect, true)) {
echo ("<tr><td>" . $item . "</td></tr>"); }