sql >> Databasteknik >  >> RDS >> Mysql

Sammanfattning av MySQL-detaljposter som matchar efter IP-adressintervall - mySQL Jedi Knight krävs

Med din befintliga datastruktur kan du göra strängmatchning enligt följande (men det är inte särskilt effektivt):

SELECT   schools.school, detail.filename, COUNT(*)
FROM     schools
    JOIN ipranges ON schools.id = ipranges.school_id
    JOIN detail   ON detail.ip_address LIKE REPLACE(ipranges.ip_range, 'x', '%')
WHERE    schools.consortium_id = ?
GROUP BY schools.school, detail.filename

Ett bättre sätt skulle vara att lagra dina IP-intervall som nätverksadress och prefixlängd:

ALTER TABLE ipranges
  ADD COLUMN network INT UNSIGNED,
  ADD COLUMN prefix  TINYINT;
UPDATE ipranges SET
  network = INET_ATON(REPLACE(ip_range, 'x', 0)),
  prefix  = 32 - 8*(CHAR_LENGTH(ip_range) - CHAR_LENGTH(REPLACE(ip_range,'x',''));
ALTER TABLE ipranges
  DROP COLUMN ip_range;

ALTER TABLE detail
  ADD COLUMN ip_address_new INT UNSIGNED;
UPDATE detail SET
  ip_address_new = INET_ATON(ip_address);
ALTER TABLE detail
  DROP COLUMN ip_address,
  CHANGE ip_address_new ip_address INT UNSIGNED;

Då skulle det bara handla om att göra några bitjämförelser:

SELECT   schools.school, detail.filename, COUNT(*)
FROM     schools
    JOIN ipranges ON schools.id = ipranges.school_id
    JOIN detail   ON detail.ip_address & ~((1 << 32 - ipranges.prefix) - 1)
                   = ipranges.network
WHERE    schools.consortium_id = ?
GROUP BY schools.school, detail.filename


  1. SQL Server-pivottabell med flera kolumnaggregat

  2. Hur gör man en databaslyssnare med java?

  3. Hur konverterar man tomma utrymmen till null-värden med hjälp av SQL Server?

  4. Hur man fixar "EXECUTE-satsen misslyckades eftersom dess WITH RESULT SETS-sats specificerade 2 kolumner för resultatuppsättningen..." Meddelande 11537 i SQL Server