在 Swift 中使用 SQL 组合人员和地址数据

news2025/1/4 15:17:06

在这里插入图片描述
在这里插入图片描述

文章目录

    • 摘要
    • 描述
      • 问题描述
      • 示例输入与输出
    • Swift 代码解决方案
    • 代码分析
    • 示例测试及结果
    • 时间复杂度
    • 空间复杂度
    • 总结

摘要

在本篇文章中,我们将讨论如何结合两个表——PersonAddress,以便生成包含每个人的姓名和地址信息的结果表。如果某人的地址信息不存在,则对应的城市和州返回为 null。我们将用 Swift 和 SQLite 数据库实现这一功能,并详细分析其逻辑。

描述

问题描述

我们有两张表:

Person 表:

列名类型
PersonIdint
FirstNamevarchar
LastNamevarchar

PersonId 是主键,用于存储每个人的基本信息,包括姓和名。

Address 表:

列名类型
AddressIdint
PersonIdint
Cityvarchar
Statevarchar

AddressId 是主键,存储每个人的城市和州信息,PersonId 是外键关联到 Person 表。

目标: 报告 Person 表中每个人的 FirstNameLastNameCityState。如果某人的地址信息在 Address 表中缺失,则其 CityState 返回 null

示例输入与输出

输入

Person 表:

PersonIdLastNameFirstName
1WangAllen
2AliceBob

Address 表:

AddressIdPersonIdCityState
12New York CityNew York
23LeetcodeCalifornia

输出

FirstNameLastNameCityState
AllenWangNullNull
BobAliceNew York CityNew York

解释

  • PersonId = 1Address 表中没有对应的地址信息,返回 null
  • PersonId = 2Address 表中找到其地址信息。

Swift 代码解决方案

以下是用 Swift 和 SQLite 数据库实现的代码:

import SQLite3

def fetchPersonWithAddress() {
    // Database setup
    var db: OpaquePointer?
    let databasePath = ":memory:" // Use in-memory database for demo
    if sqlite3_open(databasePath, &db) != SQLITE_OK {
        print("Failed to open database")
        return
    }

    // Create tables
    let createPersonTable = """
    CREATE TABLE Person (
        PersonId INTEGER PRIMARY KEY,
        FirstName TEXT,
        LastName TEXT
    );
    """

    let createAddressTable = """
    CREATE TABLE Address (
        AddressId INTEGER PRIMARY KEY,
        PersonId INTEGER,
        City TEXT,
        State TEXT
    );
    """

    if sqlite3_exec(db, createPersonTable, nil, nil, nil) != SQLITE_OK ||
       sqlite3_exec(db, createAddressTable, nil, nil, nil) != SQLITE_OK {
        print("Failed to create tables")
        sqlite3_close(db)
        return
    }

    // Insert sample data
    let insertPersonData = """
    INSERT INTO Person (PersonId, FirstName, LastName) VALUES
    (1, 'Allen', 'Wang'),
    (2, 'Bob', 'Alice');
    """

    let insertAddressData = """
    INSERT INTO Address (AddressId, PersonId, City, State) VALUES
    (1, 2, 'New York City', 'New York'),
    (2, 3, 'Leetcode', 'California');
    """

    if sqlite3_exec(db, insertPersonData, nil, nil, nil) != SQLITE_OK ||
       sqlite3_exec(db, insertAddressData, nil, nil, nil) != SQLITE_OK {
        print("Failed to insert data")
        sqlite3_close(db)
        return
    }

    // Query data with LEFT JOIN
    let query = """
    SELECT Person.FirstName, Person.LastName, Address.City, Address.State
    FROM Person
    LEFT JOIN Address ON Person.PersonId = Address.PersonId;
    """

    var statement: OpaquePointer?
    if sqlite3_prepare_v2(db, query, -1, &statement, nil) == SQLITE_OK {
        print("FirstName | LastName | City          | State")
        while sqlite3_step(statement) == SQLITE_ROW {
            let firstName = String(cString: sqlite3_column_text(statement, 0))
            let lastName = String(cString: sqlite3_column_text(statement, 1))
            let city = sqlite3_column_text(statement, 2).flatMap { String(cString: $0) } ?? "Null"
            let state = sqlite3_column_text(statement, 3).flatMap { String(cString: $0) } ?? "Null"
            print("\(firstName) | \(lastName) | \(city) | \(state)")
        }
    } else {
        print("Failed to execute query")
    }

    sqlite3_finalize(statement)
    sqlite3_close(db)
}

fetchPersonWithAddress()

代码分析

  1. 表创建与数据插入

    • 使用 SQL 创建 PersonAddress 表,并插入示例数据。
  2. 数据查询

    • 通过 LEFT JOIN 查询数据。左连接确保即使 Address 表中没有对应的 PersonIdPerson 表的记录也会出现在结果中。
  3. 结果展示

    • 使用 sqlite3_step 遍历查询结果,并处理可能的 null 值。

示例测试及结果

输出结果

FirstName | LastName | City          | State
Allen     | Wang     | Null          | Null
Bob       | Alice    | New York City | New York

时间复杂度

  • 查询操作: LEFT JOIN 的时间复杂度为 O(n + m),其中 nm 分别是 PersonAddress 表的大小。

空间复杂度

  • 额外空间: 用于存储查询结果,复杂度为 O(k),其中 k 是结果行数。

总结

本文通过 Swift 和 SQLite 实现了对两个表的合并查询,并处理了地址缺失的情况。代码逻辑清晰,适合实际应用场景如用户数据整合或报告生成。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2269614.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AAL省电效果对比

AAL省电的原理主要是‌通过根据显示内容来降低背光,然后通过调节gamma来补偿显示亮度,从而达到省电的效果‌。具体来说,gamma值越高,灰度越低,图像越暗。因此,颜色越暗的图片越省电,这也是为什么…

ArcGIS中怎么进行水文分析?(思路介绍)

最近有人咨询,ArcGIS中怎么进行水文分析,大致的说一下河网提取的思路哈 解决思路:dem填洼→计算水流方向→计算水流累积矩阵→形成河网 dem填洼 计算水流方向 计算水流累积矩阵 用栅格计算器,设阈值(自己多次尝试&…

Debian-linux运维-ssh配置(兼容Jenkins插件的ssh连接公钥类型)

系统版本:Debian 12.5、11.1 1 生成密钥对 可以用云服务商控制台生成的密钥对,也可以自己在客户端或者服务器上生成, 已经有密钥对就可以跳过这步 用户默认密钥文件路径为 ~/.ssh/id_rsa,可以在交互中指定路径,也可…

ZZNUOJ 1798:大小写判断(C/C++/Java)

题目描述 给定一个英文字母判断这个字母是大写还是小写。 输入 输入只包含一个英文字母c。 输出 如果c是大写字母,输出“upper”,否则输出“lower”。 样例输入 x 样例输出 lower 来源 蓝桥杯算法训练 常见的ASCII值 ASCII表中可以记下部分特殊的值(十进制)(字母从A到Z&am…

Wonder Dynamics技术浅析(二):人体姿态估计

Wonder Dynamics 的人体姿态估计模块旨在从图像或视频中检测并定位人体关键点(如关节、肢体等),为后续的动作捕捉、虚拟角色动画等应用提供基础数据。 一、人体姿态估计概述 人体姿态估计是指从图像或视频中检测并定位人体关键点的位置&…

前端压缩字体包方法,8MB可压缩至900K!

1、先安装压缩工具 npm install font-spider -g2、新建个文件夹,把要压缩的字体放进去,然后新建一个html,如下图 目前没有经过压缩的字体包是接近8MB 新建的html内容如下,直接复制即可 解释: 1、在样式中定义要压缩…

mysql的索引类型和索引方法

前言 在 MySQL 中,索引类型和索引方法是两个不同的概念。索引类型决定了可以存储的数据种类以及索引的功能特性,而索引方法则定义了索引数据的组织方式和查找机制。在 MySQL 中,索引(Index)是用于加快数据检索速度的数…

七种改进爬山算法的方法

一、爬山算法 爬山算法(Hill Climbing Algorithm)是一种启发式的基于局部最优解的搜索算法,用于在给定的搜索空间中寻找全局最优解或足够好的解。它属于局部搜索算法,通常用于解决优化问题,包括连续和离散问题。 爬山算法模拟了爬山的过程,从某个随机起始点开始,不断向更…

推荐5款局域网IP扫描工具,支持电脑+Android!

在日常网络管理中,快速扫描局域网中的设备和IP地址是一项基本但非常重要的任务。无论是排查网络问题还是进行设备管理,一款好用的 IP 扫描工具都能让你事半功倍。 如何选择适合自己需求的局域网 IP 扫描工具?有哪些功能强大又易于上手的工具…

微信小程序调用 WebAssembly 烹饪指南

我们都是在夜里崩溃过的俗人,所幸终会天亮。明天就是新的开始,我们会变得与昨天不同。 一、Rust 导出 wasm 参考 wasm-bindgen 官方指南 https://wasm.rust-lang.net.cn/wasm-bindgen/introduction.html wasm-bindgen,这是一个 Rust 库和 CLI…

03-栈和队列

目录 3.1栈和队列的定义和特点 3.2栈的表示和操作的实现 顺序栈的表示和实现 Ⅰ.顺序栈的初始化 Ⅱ.顺序栈的入栈 Ⅲ.顺序栈的出栈 链栈的表示和实现 Ⅰ.链栈的初始化 Ⅱ.链栈的入栈 Ⅲ.链栈的出栈 Ⅳ.取栈顶元素 Ⅴ.判断链栈是否为空 3.3栈与递归 3.4队列的表示和操…

Vue 3.0 中 template 多个根元素警告问题

在 Vue 2.0 中,template 只允许存在一个根元素,但是这种情况在 Vue 3.0 里发生了一些变化。 在 Vue 3.0 中开始支持 template 存在多个根元素了。但是因为 VSCode 中的一些插件没有及时更新,所以当你在 template 中写入多个根元素时&#xf…

vue elementUI Plus实现拖拽流程图,不引入插件,纯手写实现。

vue elementUI Plus实现拖拽流程图,不引入插件,纯手写实现。 1.设计思路:2.设计细节3.详细代码实现 1.设计思路: 左侧button列表是要拖拽的组件。中间是拖拽后的流程图。右侧是拖拽后的数据列表。 我们拖动左侧组件放入中间的流…

人工智能与传统编程的主要区别是什么?

传统编程:开发者预先编写软件行为规则,代码基于程序员定义逻辑处理输入并产生确定输出,具有确定性、手动编写规则和结构化逻辑特点,如垃圾邮件分类程序基于预设关键词等规则。AI 编程:从数据中学习而非手动编写规则&am…

电脑tkbrep.dll缺失怎么修复?

电脑运行时常见问题解析:tkbrep.dll缺失的修复策略与系统维护建议 在软件开发和电脑使用的日常中,我们时常会遇到各种系统报错和文件缺失的问题,其中tkbrep.dll的缺失便是一个较为常见的例子。作为软件开发从业者,我深知这些问题…

Nacos源码之服务注册

1. 准备工作 ​ 我们在使用Nacos作为SpringCloud中的注册中心组件时,最常用到的是它的三个功能:服务注册、服务发现和配置中心。 ​ 现在我们单机启动多个user-client,当我们成功运行UserClientApplication后可以在IDEA的service一栏中找到…

2025和数集团新年献词|和合与共,生生不息

2024年12月30日,“和数新春会”在上海环球港凯悦酒店举行,和数集团董事长兼总经理唐毅、集团高管和市场骨干欢聚一堂,共迎新春。 告别收获的2024,迎来腾飞的2025。 回望来时路,我们在挑战中砥砺前行,在困…

web 开发全局覆盖文件上传身份验证漏洞利用

全局覆盖 首先认识全局变量和局部变量 再一个就是知道全局变量是全局使用的并且有个特点就是可以覆盖 这个就是全局变量我们输出一下发现 z居然等于函数内的计算值 把我们原来定义的全局变量 $z给覆盖了 看一下局部变量 这个时候 z就不会被覆盖 <?php $x1; $y2; …

Day3 微服务 微服务保护(请求限流、线程隔离、服务熔断)、Sentinel微服务保护框架、分布式事务(XA模式、AT模式)、Seata分布式事务框架

目录 1.微服务保护 1.1.服务保护方案 1.1.1 请求限流 1.1.2 线程隔离 1.1.3 服务熔断 1.2 Sentinel 1.2.1.介绍和安装 1.2.2 微服务整合 1.2.2.1 引入sentinel依赖 1.2.2.2 配置控制台 1.2.2.3 访问cart-service的任意端点 1.3 请求限流 1.4 线程隔离 1.4.1 OpenFeign整合Senti…

使用 TensorFlow 打造企业智能数据分析平台

文章目录 摘要引言平台架构设计核心架构技术栈选型 数据采集与预处理代码详解 数据分析与预测代码详解 数据可视化ECharts 配置 总结未来展望参考资料 摘要 在大数据时代&#xff0c;企业决策正越来越依赖数据分析。然而&#xff0c;面对海量数据&#xff0c;传统分析工具常因…