ค้นหาค่าที่คั่นด้วยเครื่องหมายจุลภาคในฐานข้อมูลด้วยแบบสอบถาม SELECT MYSQL

ฉันมีปัญหาในการรับผลลัพธ์จากฐานข้อมูล ฉันมีคอลัมน์ชื่อ "ภูมิภาค" ซึ่งค่าประกอบด้วยภูมิภาคทั้งหมดที่ผู้ใช้เลือกผ่านแบบฟอร์มสมัครรับจดหมายข่าวพร้อมเครื่องหมายจุลภาค เช่น "ตะวันออกกลาง ยุโรป"

ฉันกำลังสร้างตัวกรองซึ่งจะต้องดึงรายชื่อผู้ใช้ทั้งหมดที่สมัครใช้งานในภูมิภาคใดภูมิภาคหนึ่งหรือหลายภูมิภาค ผู้ใช้สามารถเลือกได้หลายภูมิภาค จากส่วนหน้าฉันกำลังรับภูมิภาคที่เลือกทั้งหมดในรูปแบบ "ทั่วโลก, ตะวันออกกลาง" ซึ่งฉันต้องใช้ในการสืบค้น SQL ของฉันเพื่อค้นหาผู้ใช้ทั้งหมดที่มีทั่วโลกและตะวันออกกลางเป็นภูมิภาคที่เลือก

ฉันพยายามใช้ FIND_IN_SET แต่ก็ไม่ได้ช่วยอะไรจริงๆ ลองด้านล่างแล้ว

 $trimmedRegions = rtrim($sortType,', ');

 $query = "SELECT * FROM health_alerts_subscribers
            WHERE FIND_IN_SET(Regions, $trimmedRegions)";

มีความคิดเห็นใดบ้างที่ฉันจะบรรลุผลตามที่ต้องการได้อย่างไร


person Anahit DEV    schedule 22.02.2019    source แหล่งที่มา
comment
ทางออกที่ดีที่สุดคือปรับโครงสร้างฐานข้อมูลของคุณใหม่ และใช้ตารางแยกและตารางเชื่อมโยงเพื่อจัดเก็บข้อมูลนี้ คอลัมน์ที่มีข้อมูลข้อความที่ใช้ตัวคั่นจะทำให้คุณปวดใจมากขึ้นในที่สุด แทนที่จะใช้เวลาเพียงไม่กี่นาทีในการออกแบบฐานข้อมูลอย่างถูกต้อง   -  person RiggsFolly    schedule 22.02.2019
comment
ค่าประกอบด้วยภูมิภาคทั้งหมดที่ผู้ใช้เลือกผ่านแบบฟอร์มสมัครรับจดหมายข่าวพร้อมเครื่องหมายจุลภาค - ฉันเดาว่าคุณคงเสียใจกับการตัดสินใจออกแบบนั้นในตอนนี้ ข้อมูลขึ้นอยู่กับคีย์ [1NF] คีย์ทั้งหมด [2NF] และไม่มีอะไรนอกจากคีย์ [3NF] ดังนั้นช่วยฉันด้วย Codd. ผลลัพธ์อันดับ 1 ที่น่าแปลกพอบน Google สำหรับคีย์ทั้งคีย์และไม่มีอะไรนอกจากนำคุณไปสู่ ​​ดังนั้นคำถามเกี่ยวกับการทำให้ข้อมูลเป็นมาตรฐาน   -  person CD001    schedule 22.02.2019
comment
FIND_IN_SET ควรใช้งานได้ คุณสามารถแบ่งปันวิธีการใช้และประสิทธิภาพการทำงานได้หรือไม่? ฉันจะใช้เส้นทางที่ทำให้เป็นมาตรฐาน แต่ข้อมูลที่คั่นด้วยจะทำให้เกิดปัญหาเสมอ   -  person user3783243    schedule 22.02.2019
comment
@ user3783243 ฉันอัปเดตคำถามของฉันแล้ว ดังนั้นคุณแนะนำให้แยกภูมิภาคทั้งหมดออกและมีค่าเป็นใช่หรือไม่ใช่   -  person Anahit DEV    schedule 22.02.2019
comment
ฉันคิดว่าถ้าคุณต้องการแถวทั้งหมดจาก global คุณสามารถใช้เช่น %Global% ดังนั้นคุณจะต้องทำการสืบค้นตามภูมิภาค   -  person Vidal    schedule 22.02.2019
comment
@Vidal จะเป็นอย่างไรหากฉันมีตัวเลือกหลายตัวสำหรับตัวกรองเช่น Global และ Europe?   -  person Anahit DEV    schedule 22.02.2019
comment
ดูคำตอบของฉัน คุณทำ 2 อย่างโดยที่ภูมิภาคเช่น (%Global%) และภูมิภาคเช่น(%ยุโรป%)   -  person Vidal    schedule 22.02.2019
comment
คุณต้องมี FIND_IN_SET สำหรับแต่ละค่า WHERE FIND_IN_SET(Regions, 'Middle East') and FIND_IN_SET(Regions, 'Global'). ฉันจะสร้างตารางอื่นที่สัมพันธ์กับแต่ละระเบียน   -  person user3783243    schedule 22.02.2019


คำตอบ (4)


ฉันแนะนำสิ่งที่ผู้ใช้ 3783243 พูด ฉันจะไปกับ FIND_IN_SET นี่คือตัวอย่าง

SELECT {columns} FROM {table} WHERE FIND_IN_SET({item_to_search}, {comma-delimited column})

วิธีที่ดีกว่าคือการสร้างตาราง ภูมิภาค และเพิ่มภูมิภาคของคุณ จากนั้นสร้างตารางที่เกี่ยวข้องที่เรียกว่า RegionRelated (ตัวอย่าง) จากนั้นเพิ่ม ID จากภูมิภาคและตารางการเชื่อมโยง (จำนวนมากถึง มากมาย)

Table structure example

Table region
id,region
1, Middle East
2, Global

Table user
id,name
1, John
2, Jan

Table userRegion
userId,regionId
1,1
2,1

SELECT user.id,user.name,region.region from user
left join userRegion ON region.userId=user.id
left  join region
where region.region in('Middle East','Global');

ในรายการแบบเลื่อนลงของคุณ เพียงเลือกภูมิภาคทั้งหมด และเมื่อผู้ใช้เลือกภูมิภาคที่ต้องการ คุณจะต้องจัดเก็บไว้ในตาราง userRegion โดยมี INSERT INTO userRegion (userid,regionId) (1,2 ); และอื่นๆ

person blupointmedia    schedule 22.02.2019
comment
ในตำแหน่ง item_to_search ฉันควรใส่อะไร? สตริงที่มีขอบเขตคั่นด้วยเครื่องหมายจุลภาคถูกเลือกไว้? และ {comma-delimited column} ฉันใส่ชื่อคอลัมน์หรือไม่ - person Anahit DEV; 22.02.2019
comment
แล้วมีแนะนำหรือปล่าวครับ? - person Strawberry; 22.02.2019
comment
หากฉันให้แต่ละภูมิภาคเป็นคอลัมน์แยกกันและมีค่าใช่หรือไม่ใช่ มันจะแก้ปัญหาของฉันได้หรือไม่ - person Anahit DEV; 22.02.2019
comment
อนาฮิต คุณจะต้องเพิ่มคอลัมน์ใหม่ต่อไปสำหรับทุกภูมิภาคใหม่ นั่นไม่ใช่วิธีที่ถูกต้อง ฉันขอแนะนำตัวอย่างของฉันข้างต้น - person blupointmedia; 22.02.2019
comment
หากผู้ใช้เขียนอีเมลถึงคุณและบอกว่าภูมิภาคของพวกเขาไม่อยู่ในรายการ จากนั้นสิ่งที่คุณต้องทำคือเพิ่มขอบเขตใหม่ลงในตารางภูมิภาค จากนั้นทุกอย่างจะยังคงทำงานต่อไป คุณจะไม่ต้องเปลี่ยนโครงสร้างของฐานข้อมูลของคุณ - person blupointmedia; 22.02.2019
comment
ประเด็นคือภูมิภาคได้รับการแก้ไขแล้ว ได้แก่ 6 ทั่วโลก แอฟริกา ตะวันออกกลาง อเมริกา เอเชีย และยุโรป - person Anahit DEV; 22.02.2019
comment
คุณก็ไปเส้นทางนั้นเหมือนกัน ในทางเทคนิคแล้วมี 8 ฉันจะสร้างคอลัมน์บูลีนสำหรับแต่ละอันและ 1 สำหรับใช่/จริงและ 0 สำหรับไม่ใช่/เท็จ - person blupointmedia; 22.02.2019
comment
ตกลงแล้วแบบสอบถามของฉันจะเป็นเช่น select โดยที่ค่าเป็น 1 ? - person Anahit DEV; 22.02.2019
comment
เลือก {columns} จาก {table} WHERE แอฟริกา=1 หรือ asia=1 และอื่นๆ... คุณจะต้องสร้างแบบสอบถามตามการเลือกของผู้ใช้ - person blupointmedia; 22.02.2019
comment
หากได้ผลโปรดยอมรับคำตอบ ขอขอบคุณและขอให้โชคดี - person blupointmedia; 22.02.2019
comment
ใช้งานได้ :) ขอบคุณมาก - person Anahit DEV; 22.02.2019

คุณจำเป็นต้องจัดรูปแบบ sql ของคุณดังนี้:

SELECT
    *
FROM
    table
WHERE
    regions = 'Europe' or
    regions like 'Europe,%' or
    regions like '%,Europe' or
    regions like '%,Europe,%' or
    regions = 'Middle East' or
    regions like 'Middle East,%' or
    regions like '%,Middle East' or
    regions like '%,Middle East,%'

ใน PHP คุณจะต้องวนซ้ำภูมิภาคที่ผู้ใช้เลือกและสร้างแบบสอบถามแบบไดนามิกเช่นนี้

person MonkeyZeus    schedule 22.02.2019
comment
เหตุใดจึงมีการถูกใจมากมาย คุณสามารถใช้หนึ่งไวด์และจุดเริ่มต้นและอีกหนึ่งรายการในตอนท้าย เช่น %value% - person Vidal; 22.02.2019
comment
@Vidal ฉันไม่รู้ว่ารายการภูมิภาคทั้งหมดจะเป็นอย่างไร ดังนั้นหาก regions มีบางอย่างเช่น Global,Middle East,Europe,East,Asia ดังนั้น %East% จะส่งกลับผลลัพธ์มากเกินไป - person MonkeyZeus; 22.02.2019
comment
@Vidal ฉันแน่ใจว่าเป็นไปได้ที่จะ REGEXP_LIKE() สถานการณ์ทั้งหมดนี้ แต่ฉันไม่มีความอดทนที่จะคิดออกสำหรับ OP พวกเขาควรจัดโต๊ะให้เป็นปกติและดำเนินชีวิตต่อไป มันจะเป็นการแสดงบ้าบอจริงๆ หากภูมิภาคเปลี่ยนชื่อ การใช้อักษรตัวพิมพ์ใหญ่ หรือแตกออกเป็นหลายภูมิภาคหรืออะไรสักอย่าง - person MonkeyZeus; 22.02.2019

ฉันสามารถแนะนำวิธีนี้ได้

SELECT * FROM table
WHERE 
   region like("%Global%")
   and region like ("%Middle East%")

ด้วยวิธีนี้คุณสามารถให้ผู้คนสมัครรับข้อมูลทั้งสองรายการได้ คุณสามารถปรับแต่งได้ตามความต้องการ แน่นอนว่าจะไม่ใช่ทางออกที่ดีที่สุด แต่คุณสามารถใช้มันเพื่อสร้างตารางสรุปข้อมูลได้ในกรณีที่คุณต้องการอัปเดตโครงสร้างฐานข้อมูลของคุณ

person Vidal    schedule 22.02.2019
comment
แต่เช่นนี้ ฉันจะมีคำขอมากมาย และฉันต้องเลือกผลลัพธ์ที่เลือก ไม่ใช่แบบคงที่ - person Anahit DEV; 22.02.2019
comment
คุณต้องการรับรายการสมัครสมาชิกเพื่อส่งอีเมลหรือไม่? มีจุดประสงค์อะไรเพื่อดูว่าฉันสามารถให้คำตอบที่ดีกว่าแก่คุณได้หรือไม่? - person Vidal; 22.02.2019
comment
ใช่ ฉันจะต้องได้รับรายชื่อซึ่งจะนำเข้าไปยังรายชื่อผู้รับจดหมายตามภูมิภาค - person Anahit DEV; 22.02.2019
comment
ตกลง คุณสามารถทำการสืบค้น [SELECT * FROM table WHERE Region like(%Global%)] และรับสมาชิกทั่วโลกทั้งหมด จากนั้นบันทึกลงใน Global Mailing list จากนั้นจึงทำการสืบค้นสำหรับภูมิภาคถัดไปในตะวันออกกลางและลูกชาย . - person Vidal; 22.02.2019
comment
โอเค แต่ฉันจะทำอย่างไรกับผู้ใช้ที่มีหลายภูมิภาคเป็นค่า ด้วยแบบสอบถามเดียว มันไม่ได้นำผู้ใช้นั้นมา - person Anahit DEV; 22.02.2019
comment
ฉันคิดว่านี่ไม่ใช่การค้นหาครั้งเดียว คุณอาจต้องค้นหาภูมิภาคต่างๆ ทั้งหมดทีละรายการ ผู้ใช้ที่สมัครรับข้อมูลหลายภูมิภาคพวกเขาจะอยู่ในรายชื่ออีเมลที่เกี่ยวข้องอาจหลายรายการตามที่พวกเขาเลือก - person Vidal; 22.02.2019
comment
ดังนั้นหากฉันมีขอบเขตทั้งหมดในคอลัมน์แยกกันโดยมีค่าใช่หรือไม่ใช่ ฉันจะได้ผลลัพธ์หรือไม่ ผู้ใช้จำเป็นต้องได้รับอีเมลเดียวที่มีทุกภูมิภาค ไม่ใช่หลายอีเมล - person Anahit DEV; 22.02.2019
comment
ตกลง ตอนนี้ฉันสับสน หากคุณกำลังจะส่งภูมิภาคของผู้ใช้ทางไปรษณีย์ เพียงสอบถามตารางโดยไม่มีตัวกรองตำแหน่งหรือภูมิภาค คุณอยากได้อะไรจากโต๊ะ? จุดประสงค์อะไรถ้าคุณสามารถแบ่งปันสิ่งนั้นได้? - person Vidal; 22.02.2019
comment
ฉันต้องส่งอีเมลแจ้งข่าวสารผู้ใช้เกี่ยวกับภูมิภาคที่เขาเลือก ดังนั้นฉันจึงต้องการทราบว่าผู้ใช้รายใดเป็นตัวอย่างสำหรับยุโรปและเอเชีย ดังนั้นฉันจึงส่งออกรายการนั้น - person Anahit DEV; 22.02.2019
comment
คุณส่งอีเมลที่แตกต่างกันสำหรับแต่ละภูมิภาคหรือไม่? - person Vidal; 22.02.2019
comment
ตกลง ความคิดเห็นที่ 4 ของฉันคือสิ่งที่คุณต้องการ คุณจะต้องทำการสืบค้นตามภูมิภาค - person Vidal; 22.02.2019

ไม่มีฟังก์ชันที่ตรงกับความต้องการของคุณ แต่คุณสามารถใช้โค้ดด้านล่างได้:

$trimmedRegions = rtrim($sortType,', ');
$trimmedRegionsCollection = explode(",", $trimmedRegions);
$trimmedRegionsRegex = implode("|", $trimmedRegionsCollection); // make string like Global|Middle East

$query = 'SELECT * from health_alerts_subscribers WHERE CONCAT(",", `Regions`, ",") REGEXP ",('.$trimmedRegionsRegex.'),"';

หวังว่ามันจะช่วยคุณได้

person Rohit Mittal    schedule 22.02.2019